1 /*
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 
19 #define LOG_TAG "FrameEvents"
20 
21 #include <LibGuiProperties.sysprop.h>
22 #include <android-base/stringprintf.h>
23 #include <cutils/compiler.h>  // For CC_[UN]LIKELY
24 #include <inttypes.h>
25 #include <utils/Log.h>
26 
27 #include <algorithm>
28 #include <limits>
29 #include <numeric>
30 
31 namespace android {
32 
33 using base::StringAppendF;
34 
35 // ============================================================================
36 // FrameEvents
37 // ============================================================================
38 
hasPostedInfo() const39 bool FrameEvents::hasPostedInfo() const {
40     return FrameEvents::isValidTimestamp(postedTime);
41 }
42 
hasRequestedPresentInfo() const43 bool FrameEvents::hasRequestedPresentInfo() const {
44     return FrameEvents::isValidTimestamp(requestedPresentTime);
45 }
46 
hasLatchInfo() const47 bool FrameEvents::hasLatchInfo() const {
48     return FrameEvents::isValidTimestamp(latchTime);
49 }
50 
hasFirstRefreshStartInfo() const51 bool FrameEvents::hasFirstRefreshStartInfo() const {
52     return FrameEvents::isValidTimestamp(firstRefreshStartTime);
53 }
54 
hasLastRefreshStartInfo() const55 bool FrameEvents::hasLastRefreshStartInfo() const {
56     // The last refresh start time may continue to update until a new frame
57     // is latched. We know we have the final value once the release info is set.
58     return addReleaseCalled;
59 }
60 
hasDequeueReadyInfo() const61 bool FrameEvents::hasDequeueReadyInfo() const {
62     return FrameEvents::isValidTimestamp(dequeueReadyTime);
63 }
64 
hasAcquireInfo() const65 bool FrameEvents::hasAcquireInfo() const {
66     return acquireFence->isValid();
67 }
68 
hasGpuCompositionDoneInfo() const69 bool 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 
hasDisplayPresentInfo() const75 bool FrameEvents::hasDisplayPresentInfo() const {
76     // We may not get a displayPresent in addPostComposite for HWC1.
77     return addPostCompositeCalled;
78 }
79 
hasReleaseInfo() const80 bool FrameEvents::hasReleaseInfo() const {
81     return addReleaseCalled;
82 }
83 
checkFencesForCompletion()84 void FrameEvents::checkFencesForCompletion() {
85     acquireFence->getSignalTime();
86     gpuCompositionDoneFence->getSignalTime();
87     displayPresentFence->getSignalTime();
88     releaseFence->getSignalTime();
89 }
90 
dumpFenceTime(std::string & outString,const char * name,bool pending,const FenceTime & fenceTime)91 static void dumpFenceTime(std::string& outString, const char* name, bool pending,
92                           const FenceTime& fenceTime) {
93     StringAppendF(&outString, "--- %s", name);
94     nsecs_t signalTime = fenceTime.getCachedSignalTime();
95     if (Fence::isValidTimestamp(signalTime)) {
96         StringAppendF(&outString, "%" PRId64 "\n", signalTime);
97     } else if (pending || signalTime == Fence::SIGNAL_TIME_PENDING) {
98         outString.append("Pending\n");
99     } else if (&fenceTime == FenceTime::NO_FENCE.get()){
100         outString.append("N/A\n");
101     } else {
102         outString.append("Error\n");
103     }
104 }
105 
dump(std::string & outString) const106 void FrameEvents::dump(std::string& outString) const {
107     if (!valid) {
108         return;
109     }
110 
111     StringAppendF(&outString, "-- Frame %" PRIu64 "\n", frameNumber);
112     StringAppendF(&outString, "--- Posted      \t%" PRId64 "\n", postedTime);
113     StringAppendF(&outString, "--- Req. Present\t%" PRId64 "\n", requestedPresentTime);
114 
115     outString.append("--- Latched     \t");
116     if (FrameEvents::isValidTimestamp(latchTime)) {
117         StringAppendF(&outString, "%" PRId64 "\n", latchTime);
118     } else {
119         outString.append("Pending\n");
120     }
121 
122     outString.append("--- Refresh (First)\t");
123     if (FrameEvents::isValidTimestamp(firstRefreshStartTime)) {
124         StringAppendF(&outString, "%" PRId64 "\n", firstRefreshStartTime);
125     } else {
126         outString.append("Pending\n");
127     }
128 
129     outString.append("--- Refresh (Last)\t");
130     if (FrameEvents::isValidTimestamp(lastRefreshStartTime)) {
131         StringAppendF(&outString, "%" PRId64 "\n", lastRefreshStartTime);
132     } else {
133         outString.append("Pending\n");
134     }
135 
136     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);
142 
143     outString.append("--- DequeueReady  \t");
144     if (FrameEvents::isValidTimestamp(dequeueReadyTime)) {
145         StringAppendF(&outString, "%" PRId64 "\n", dequeueReadyTime);
146     } else {
147         outString.append("Pending\n");
148     }
149 
150     dumpFenceTime(outString, "Release           \t",
151             true, *releaseFence);
152 }
153 
154 
155 // ============================================================================
156 // FrameEventHistory
157 // ============================================================================
158 
159 namespace {
160 
161 struct FrameNumberEqual {
FrameNumberEqualandroid::__anonef3216d50111::FrameNumberEqual162     explicit FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
operator ()android::__anonef3216d50111::FrameNumberEqual163     bool operator()(const FrameEvents& frame) {
164         return frame.valid && mFrameNumber == frame.frameNumber;
165     }
166     const uint64_t mFrameNumber;
167 };
168 
169 }  // namespace
170 
171 const size_t FrameEventHistory::INITIAL_MAX_FRAME_HISTORY =
172         sysprop::LibGuiProperties::frame_event_history_size().value_or(8);
173 
FrameEventHistory()174 FrameEventHistory::FrameEventHistory()
175       : mFrames(std::vector<FrameEvents>(INITIAL_MAX_FRAME_HISTORY)) {}
176 
177 FrameEventHistory::~FrameEventHistory() = default;
178 
getFrame(uint64_t frameNumber)179 FrameEvents* 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 
getFrame(uint64_t frameNumber,size_t * iHint)185 FrameEvents* 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 
checkFencesForCompletion()201 void FrameEventHistory::checkFencesForCompletion() {
202     for (auto& frame : mFrames) {
203         frame.checkFencesForCompletion();
204     }
205 }
206 
207 // Uses !|valid| as the MSB.
FrameNumberLessThan(const FrameEvents & lhs,const FrameEvents & rhs)208 static 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 
dump(std::string & outString) const216 void FrameEventHistory::dump(std::string& outString) const {
217     auto earliestFrame = std::min_element(
218             mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
219     if (!earliestFrame->valid) {
220         outString.append("-- N/A\n");
221         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 
231 // ============================================================================
232 // ProducerFrameEventHistory
233 // ============================================================================
234 
235 ProducerFrameEventHistory::~ProducerFrameEventHistory() = default;
236 
snapToNextTick(nsecs_t timestamp,nsecs_t tickPhase,nsecs_t tickInterval)237 nsecs_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 
getNextCompositeDeadline(const nsecs_t now) const248 nsecs_t ProducerFrameEventHistory::getNextCompositeDeadline(
249         const nsecs_t now) const{
250     return snapToNextTick(
251             now, mCompositorTiming.deadline, mCompositorTiming.interval);
252 }
253 
updateAcquireFence(uint64_t frameNumber,std::shared_ptr<FenceTime> && acquire)254 void ProducerFrameEventHistory::updateAcquireFence(
255         uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) {
256     FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
257     if (frame == nullptr) {
258         return;
259     }
260 
261     if (acquire->isValid()) {
262         mAcquireTimeline.push(acquire);
263         frame->acquireFence = std::move(acquire);
264     } else {
265         // If there isn't an acquire fence, assume that buffer was
266         // ready for the consumer when posted.
267         frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
268     }
269 }
270 
applyDelta(const FrameEventHistoryDelta & delta)271 void ProducerFrameEventHistory::applyDelta(
272         const FrameEventHistoryDelta& delta) {
273     mCompositorTiming = delta.mCompositorTiming;
274 
275     // 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 
282     for (auto& d : delta.mDeltas) {
283         // Avoid out-of-bounds access.
284         if (CC_UNLIKELY(d.mIndex >= mFrames.size())) {
285             ALOGE("applyDelta: Bad index.");
286             return;
287         }
288 
289         FrameEvents& frame = mFrames[d.mIndex];
290 
291         frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
292         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;
299         frame.dequeueReadyTime = d.mDequeueReadyTime;
300 
301         if (frame.frameNumber != d.mFrameNumber) {
302             // We got a new frame. Initialize some of the fields.
303             frame.frameNumber = d.mFrameNumber;
304             frame.acquireFence = FenceTime::NO_FENCE;
305             frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
306             frame.displayPresentFence = FenceTime::NO_FENCE;
307             frame.releaseFence = FenceTime::NO_FENCE;
308             // The consumer only sends valid frames.
309             frame.valid = true;
310         }
311 
312         applyFenceDelta(&mGpuCompositionDoneTimeline,
313                 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
314         applyFenceDelta(&mPresentTimeline,
315                 &frame.displayPresentFence, d.mDisplayPresentFence);
316         applyFenceDelta(&mReleaseTimeline,
317                 &frame.releaseFence, d.mReleaseFence);
318     }
319 }
320 
updateSignalTimes()321 void ProducerFrameEventHistory::updateSignalTimes() {
322     mAcquireTimeline.updateSignalTimes();
323     mGpuCompositionDoneTimeline.updateSignalTimes();
324     mPresentTimeline.updateSignalTimes();
325     mReleaseTimeline.updateSignalTimes();
326 }
327 
applyFenceDelta(FenceTimeline * timeline,std::shared_ptr<FenceTime> * dst,const FenceTime::Snapshot & src) const328 void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
329         std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
330     if (CC_UNLIKELY(dst == nullptr || dst->get() == nullptr)) {
331         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:
339             ALOGE_IF((*dst)->isValid(), "applyFenceDelta: Unexpected fence.");
340             *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 
createFenceTime(const sp<Fence> & fence) const353 std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
354         const sp<Fence>& fence) const {
355     return std::make_shared<FenceTime>(fence);
356 }
357 
resize(size_t newSize)358 void 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 }
393 
394 // ============================================================================
395 // ConsumerFrameEventHistory
396 // ============================================================================
397 
ConsumerFrameEventHistory()398 ConsumerFrameEventHistory::ConsumerFrameEventHistory()
399       : mFramesDirty(std::vector<FrameEventDirtyFields>(INITIAL_MAX_FRAME_HISTORY)) {}
400 
401 ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
402 
onDisconnect()403 void ConsumerFrameEventHistory::onDisconnect() {
404     mCurrentConnectId++;
405     mProducerWantsEvents = false;
406 }
407 
setProducerWantsEvents()408 void ConsumerFrameEventHistory::setProducerWantsEvents() {
409     mProducerWantsEvents = true;
410 }
411 
initializeCompositorTiming(const CompositorTiming & compositorTiming)412 void ConsumerFrameEventHistory::initializeCompositorTiming(
413         const CompositorTiming& compositorTiming) {
414     mCompositorTiming = compositorTiming;
415 }
416 
addQueue(const NewFrameEventsEntry & newEntry)417 void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
418     // Overwrite all fields of the frame with default values unless set here.
419     FrameEvents newTimestamps;
420     newTimestamps.connectId = mCurrentConnectId;
421     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;
427 
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.
431     mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
432 
433     mQueueOffset = (mQueueOffset + 1) % mFrames.size();
434 }
435 
addLatch(uint64_t frameNumber,nsecs_t latchTime)436 void ConsumerFrameEventHistory::addLatch(
437         uint64_t frameNumber, nsecs_t latchTime) {
438     FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
439     if (frame == nullptr) {
440         ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
441         return;
442     }
443     frame->latchTime = latchTime;
444     mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
445 }
446 
addPreComposition(uint64_t frameNumber,nsecs_t refreshStartTime)447 void ConsumerFrameEventHistory::addPreComposition(
448         uint64_t frameNumber, nsecs_t refreshStartTime) {
449     FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
450     if (frame == nullptr) {
451         ALOGE_IF(mProducerWantsEvents,
452                 "addPreComposition: Did not find frame.");
453         return;
454     }
455     frame->lastRefreshStartTime = refreshStartTime;
456     mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
457     if (!FrameEvents::isValidTimestamp(frame->firstRefreshStartTime)) {
458         frame->firstRefreshStartTime = refreshStartTime;
459         mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
460     }
461 }
462 
addPostComposition(uint64_t frameNumber,const std::shared_ptr<FenceTime> & gpuCompositionDone,const std::shared_ptr<FenceTime> & displayPresent,const CompositorTiming & compositorTiming)463 void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
464         const std::shared_ptr<FenceTime>& gpuCompositionDone,
465         const std::shared_ptr<FenceTime>& displayPresent,
466         const CompositorTiming& compositorTiming) {
467     mCompositorTiming = compositorTiming;
468 
469     FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
470     if (frame == nullptr) {
471         ALOGE_IF(mProducerWantsEvents,
472                 "addPostComposition: Did not find frame.");
473         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;
479         mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GPU_COMPOSITION_DONE>();
480         if (!frame->displayPresentFence->isValid()) {
481             frame->displayPresentFence = displayPresent;
482             mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
483         }
484     }
485 }
486 
addRelease(uint64_t frameNumber,nsecs_t dequeueReadyTime,std::shared_ptr<FenceTime> && release)487 void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber,
488         nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) {
489     FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
490     if (frame == nullptr) {
491         ALOGE_IF(mProducerWantsEvents, "addRelease: Did not find frame.");
492         return;
493     }
494     frame->addReleaseCalled = true;
495     frame->dequeueReadyTime = dequeueReadyTime;
496     frame->releaseFence = std::move(release);
497     mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
498 }
499 
getFrameDelta(FrameEventHistoryDelta * delta,const std::vector<FrameEvents>::iterator & frame)500 void ConsumerFrameEventHistory::getFrameDelta(FrameEventHistoryDelta* delta,
501                                               const std::vector<FrameEvents>::iterator& frame) {
502     mProducerWantsEvents = true;
503     size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
504     if (mFramesDirty[i].anyDirty()) {
505         // 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         }
511         mFramesDirty[i].reset();
512     }
513 }
514 
getAndResetDelta(FrameEventHistoryDelta * delta)515 void ConsumerFrameEventHistory::getAndResetDelta(
516         FrameEventHistoryDelta* delta) {
517     mProducerWantsEvents = true;
518     delta->mCompositorTiming = mCompositorTiming;
519 
520     // 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.
522     delta->mDeltas.reserve(mFramesDirty.size());
523     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);
530     }
531 }
532 
resize(size_t newSize)533 void 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 }
563 
564 // ============================================================================
565 // FrameEventsDelta
566 // ============================================================================
567 
FrameEventsDelta(size_t index,const FrameEvents & frameTimestamps,const FrameEventDirtyFields & dirtyFields)568 FrameEventsDelta::FrameEventsDelta(
569         size_t index,
570         const FrameEvents& frameTimestamps,
571         const FrameEventDirtyFields& dirtyFields)
572     : mIndex(index),
573       mFrameNumber(frameTimestamps.frameNumber),
574       mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
575       mAddReleaseCalled(frameTimestamps.addReleaseCalled),
576       mPostedTime(frameTimestamps.postedTime),
577       mRequestedPresentTime(frameTimestamps.requestedPresentTime),
578       mLatchTime(frameTimestamps.latchTime),
579       mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
580       mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime),
581       mDequeueReadyTime(frameTimestamps.dequeueReadyTime) {
582     if (dirtyFields.isDirty<FrameEvent::GPU_COMPOSITION_DONE>()) {
583         mGpuCompositionDoneFence =
584                 frameTimestamps.gpuCompositionDoneFence->getSnapshot();
585     }
586     if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
587         mDisplayPresentFence =
588                 frameTimestamps.displayPresentFence->getSnapshot();
589     }
590     if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
591         mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
592     }
593 }
594 
minFlattenedSize()595 constexpr size_t FrameEventsDelta::minFlattenedSize() {
596     return sizeof(FrameEventsDelta::mFrameNumber) +
597             sizeof(uint16_t) + // mIndex
598             sizeof(uint8_t) + // mAddPostCompositeCalled
599             sizeof(uint8_t) + // mAddReleaseCalled
600             sizeof(FrameEventsDelta::mPostedTime) +
601             sizeof(FrameEventsDelta::mRequestedPresentTime) +
602             sizeof(FrameEventsDelta::mLatchTime) +
603             sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
604             sizeof(FrameEventsDelta::mLastRefreshStartTime) +
605             sizeof(FrameEventsDelta::mDequeueReadyTime);
606 }
607 
608 // Flattenable implementation
getFlattenedSize() const609 size_t FrameEventsDelta::getFlattenedSize() const {
610     auto fences = allFences(this);
611     return minFlattenedSize() +
612             std::accumulate(fences.begin(), fences.end(), size_t(0),
613                     [](size_t a, const FenceTime::Snapshot* fence) {
614                             return a + fence->getFlattenedSize();
615                     });
616 }
617 
getFdCount() const618 size_t FrameEventsDelta::getFdCount() const {
619     auto fences = allFences(this);
620     return std::accumulate(fences.begin(), fences.end(), size_t(0),
621             [](size_t a, const FenceTime::Snapshot* fence) {
622                 return a + fence->getFdCount();
623             });
624 }
625 
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const626 status_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 
632     if (mIndex >= UINT8_MAX || mIndex < 0) {
633         return BAD_VALUE;
634     }
635 
636     FlattenableUtils::write(buffer, size, mFrameNumber);
637 
638     // These are static_cast to uint16_t/uint8_t for alignment.
639     FlattenableUtils::write(buffer, size, static_cast<uint16_t>(mIndex));
640     FlattenableUtils::write(
641             buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
642     FlattenableUtils::write(
643             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);
650     FlattenableUtils::write(buffer, size, mDequeueReadyTime);
651 
652     // Fences
653     for (auto fence : allFences(this)) {
654         status_t status = fence->flatten(buffer, size, fds, count);
655         if (status != NO_ERROR) {
656             return status;
657         }
658     }
659     return NO_ERROR;
660 }
661 
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)662 status_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 
670     // These were written as uint16_t/uint8_t for alignment.
671     uint16_t temp16 = 0;
672     FlattenableUtils::read(buffer, size, temp16);
673     mIndex = temp16;
674     if (mIndex >= UINT8_MAX) {
675         return BAD_VALUE;
676     }
677     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);
682 
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);
688     FlattenableUtils::read(buffer, size, mDequeueReadyTime);
689 
690     // Fences
691     for (auto fence : allFences(this)) {
692         status_t status = fence->unflatten(buffer, size, fds, count);
693         if (status != NO_ERROR) {
694             return status;
695         }
696     }
697     return NO_ERROR;
698 }
699 
getFrameNumber() const700 uint64_t FrameEventsDelta::getFrameNumber() const {
701     return mFrameNumber;
702 }
703 
getLatchTime(nsecs_t * latchTime) const704 bool FrameEventsDelta::getLatchTime(nsecs_t* latchTime) const {
705     if (mLatchTime == FrameEvents::TIMESTAMP_PENDING) {
706         return false;
707     }
708     *latchTime = mLatchTime;
709     return true;
710 }
711 
getDisplayPresentFence(sp<Fence> * fence) const712 bool 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 }
719 
720 // ============================================================================
721 // FrameEventHistoryDelta
722 // ============================================================================
723 
operator =(FrameEventHistoryDelta && src)724 FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
725         FrameEventHistoryDelta&& src) noexcept {
726     mCompositorTiming = src.mCompositorTiming;
727 
728     if (CC_UNLIKELY(!mDeltas.empty())) {
729         ALOGE("FrameEventHistoryDelta assign clobbering history.");
730     }
731     mDeltas = std::move(src.mDeltas);
732     return *this;
733 }
734 
minFlattenedSize()735 constexpr size_t FrameEventHistoryDelta::minFlattenedSize() {
736     return sizeof(uint32_t) + // mDeltas.size()
737             sizeof(mCompositorTiming);
738 }
739 
getFlattenedSize() const740 size_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 
getFdCount() const748 size_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 
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const755 status_t FrameEventHistoryDelta::flatten(
756             void*& buffer, size_t& size, int*& fds, size_t& count) const {
757     if (mDeltas.size() > UINT8_MAX) {
758         return BAD_VALUE;
759     }
760     if (size < getFlattenedSize()) {
761         return NO_MEMORY;
762     }
763 
764     FlattenableUtils::write(buffer, size, mCompositorTiming);
765 
766     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 
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)777 status_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 
783     FlattenableUtils::read(buffer, size, mCompositorTiming);
784 
785     uint32_t deltaCount = 0;
786     FlattenableUtils::read(buffer, size, deltaCount);
787     if (deltaCount > UINT8_MAX) {
788         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 
begin() const800 std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::begin() const {
801     return mDeltas.begin();
802 }
803 
end() const804 std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::end() const {
805     return mDeltas.end();
806 }
807 
808 } // namespace android
809