• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::__anon96b2c21a0111::FrameNumberEqual162     explicit FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
operator ()android::__anon96b2c21a0111::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         ALOGE("updateAcquireFence: Did not find frame.");
259         return;
260     }
261 
262     if (acquire->isValid()) {
263         mAcquireTimeline.push(acquire);
264         frame->acquireFence = std::move(acquire);
265     } else {
266         // If there isn't an acquire fence, assume that buffer was
267         // ready for the consumer when posted.
268         frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
269     }
270 }
271 
applyDelta(const FrameEventHistoryDelta & delta)272 void ProducerFrameEventHistory::applyDelta(
273         const FrameEventHistoryDelta& delta) {
274     mCompositorTiming = delta.mCompositorTiming;
275 
276     // Deltas should have enough reserved capacity for the consumer-side, therefore if there's a
277     // different capacity, we re-sized on the consumer side and now need to resize on the producer
278     // side.
279     if (delta.mDeltas.capacity() > mFrames.capacity()) {
280         resize(delta.mDeltas.capacity());
281     }
282 
283     for (auto& d : delta.mDeltas) {
284         // Avoid out-of-bounds access.
285         if (CC_UNLIKELY(d.mIndex >= mFrames.size())) {
286             ALOGE("applyDelta: Bad index.");
287             return;
288         }
289 
290         FrameEvents& frame = mFrames[d.mIndex];
291 
292         frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
293         frame.addReleaseCalled = d.mAddReleaseCalled != 0;
294 
295         frame.postedTime = d.mPostedTime;
296         frame.requestedPresentTime = d.mRequestedPresentTime;
297         frame.latchTime = d.mLatchTime;
298         frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
299         frame.lastRefreshStartTime = d.mLastRefreshStartTime;
300         frame.dequeueReadyTime = d.mDequeueReadyTime;
301 
302         if (frame.frameNumber != d.mFrameNumber) {
303             // We got a new frame. Initialize some of the fields.
304             frame.frameNumber = d.mFrameNumber;
305             frame.acquireFence = FenceTime::NO_FENCE;
306             frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
307             frame.displayPresentFence = FenceTime::NO_FENCE;
308             frame.releaseFence = FenceTime::NO_FENCE;
309             // The consumer only sends valid frames.
310             frame.valid = true;
311         }
312 
313         applyFenceDelta(&mGpuCompositionDoneTimeline,
314                 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
315         applyFenceDelta(&mPresentTimeline,
316                 &frame.displayPresentFence, d.mDisplayPresentFence);
317         applyFenceDelta(&mReleaseTimeline,
318                 &frame.releaseFence, d.mReleaseFence);
319     }
320 }
321 
updateSignalTimes()322 void ProducerFrameEventHistory::updateSignalTimes() {
323     mAcquireTimeline.updateSignalTimes();
324     mGpuCompositionDoneTimeline.updateSignalTimes();
325     mPresentTimeline.updateSignalTimes();
326     mReleaseTimeline.updateSignalTimes();
327 }
328 
applyFenceDelta(FenceTimeline * timeline,std::shared_ptr<FenceTime> * dst,const FenceTime::Snapshot & src) const329 void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
330         std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
331     if (CC_UNLIKELY(dst == nullptr || dst->get() == nullptr)) {
332         ALOGE("applyFenceDelta: dst is null.");
333         return;
334     }
335 
336     switch (src.state) {
337         case FenceTime::Snapshot::State::EMPTY:
338             return;
339         case FenceTime::Snapshot::State::FENCE:
340             ALOGE_IF((*dst)->isValid(), "applyFenceDelta: Unexpected fence.");
341             *dst = createFenceTime(src.fence);
342             timeline->push(*dst);
343             return;
344         case FenceTime::Snapshot::State::SIGNAL_TIME:
345             if ((*dst)->isValid()) {
346                 (*dst)->applyTrustedSnapshot(src);
347             } else {
348                 *dst = std::make_shared<FenceTime>(src.signalTime);
349             }
350             return;
351     }
352 }
353 
createFenceTime(const sp<Fence> & fence) const354 std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
355         const sp<Fence>& fence) const {
356     return std::make_shared<FenceTime>(fence);
357 }
358 
resize(size_t newSize)359 void ProducerFrameEventHistory::resize(size_t newSize) {
360     // we don't want to drop events by resizing too small, so don't resize in the negative direction
361     if (newSize <= mFrames.size()) {
362         return;
363     }
364 
365     // This algorithm for resizing needs to be the same as ConsumerFrameEventHistory::resize,
366     // because the indexes need to match when communicating the FrameEventDeltas.
367 
368     // We need to find the oldest frame, because that frame needs to move to index 0 in the new
369     // frame history.
370     size_t oldestFrameIndex = 0;
371     size_t oldestFrameNumber = INT32_MAX;
372     for (size_t i = 0; i < mFrames.size(); ++i) {
373         if (mFrames[i].frameNumber < oldestFrameNumber && mFrames[i].valid) {
374             oldestFrameNumber = mFrames[i].frameNumber;
375             oldestFrameIndex = i;
376         }
377     }
378 
379     // move the existing frame information into a new vector, so that the oldest frames are at
380     // index 0, and the latest frames are at the end of the vector
381     std::vector<FrameEvents> newFrames(newSize);
382     size_t oldI = oldestFrameIndex;
383     size_t newI = 0;
384     do {
385         if (mFrames[oldI].valid) {
386             newFrames[newI++] = std::move(mFrames[oldI]);
387         }
388         oldI = (oldI + 1) % mFrames.size();
389     } while (oldI != oldestFrameIndex);
390 
391     mFrames = std::move(newFrames);
392     mAcquireOffset = 0; // this is just a hint, so setting this to anything is fine
393 }
394 
395 // ============================================================================
396 // ConsumerFrameEventHistory
397 // ============================================================================
398 
ConsumerFrameEventHistory()399 ConsumerFrameEventHistory::ConsumerFrameEventHistory()
400       : mFramesDirty(std::vector<FrameEventDirtyFields>(INITIAL_MAX_FRAME_HISTORY)) {}
401 
402 ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
403 
onDisconnect()404 void ConsumerFrameEventHistory::onDisconnect() {
405     mCurrentConnectId++;
406     mProducerWantsEvents = false;
407 }
408 
setProducerWantsEvents()409 void ConsumerFrameEventHistory::setProducerWantsEvents() {
410     mProducerWantsEvents = true;
411 }
412 
initializeCompositorTiming(const CompositorTiming & compositorTiming)413 void ConsumerFrameEventHistory::initializeCompositorTiming(
414         const CompositorTiming& compositorTiming) {
415     mCompositorTiming = compositorTiming;
416 }
417 
addQueue(const NewFrameEventsEntry & newEntry)418 void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
419     // Overwrite all fields of the frame with default values unless set here.
420     FrameEvents newTimestamps;
421     newTimestamps.connectId = mCurrentConnectId;
422     newTimestamps.frameNumber = newEntry.frameNumber;
423     newTimestamps.postedTime = newEntry.postedTime;
424     newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
425     newTimestamps.acquireFence = newEntry.acquireFence;
426     newTimestamps.valid = true;
427     mFrames[mQueueOffset] = newTimestamps;
428 
429     // Note: We avoid sending the acquire fence back to the caller since
430     // they have the original one already, so there is no need to set the
431     // acquire dirty bit.
432     mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
433 
434     mQueueOffset = (mQueueOffset + 1) % mFrames.size();
435 }
436 
addLatch(uint64_t frameNumber,nsecs_t latchTime)437 void ConsumerFrameEventHistory::addLatch(
438         uint64_t frameNumber, nsecs_t latchTime) {
439     FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
440     if (frame == nullptr) {
441         ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
442         return;
443     }
444     frame->latchTime = latchTime;
445     mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
446 }
447 
addPreComposition(uint64_t frameNumber,nsecs_t refreshStartTime)448 void ConsumerFrameEventHistory::addPreComposition(
449         uint64_t frameNumber, nsecs_t refreshStartTime) {
450     FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
451     if (frame == nullptr) {
452         ALOGE_IF(mProducerWantsEvents,
453                 "addPreComposition: Did not find frame.");
454         return;
455     }
456     frame->lastRefreshStartTime = refreshStartTime;
457     mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
458     if (!FrameEvents::isValidTimestamp(frame->firstRefreshStartTime)) {
459         frame->firstRefreshStartTime = refreshStartTime;
460         mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
461     }
462 }
463 
addPostComposition(uint64_t frameNumber,const std::shared_ptr<FenceTime> & gpuCompositionDone,const std::shared_ptr<FenceTime> & displayPresent,const CompositorTiming & compositorTiming)464 void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
465         const std::shared_ptr<FenceTime>& gpuCompositionDone,
466         const std::shared_ptr<FenceTime>& displayPresent,
467         const CompositorTiming& compositorTiming) {
468     mCompositorTiming = compositorTiming;
469 
470     FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
471     if (frame == nullptr) {
472         ALOGE_IF(mProducerWantsEvents,
473                 "addPostComposition: Did not find frame.");
474         return;
475     }
476     // Only get GPU and present info for the first composite.
477     if (!frame->addPostCompositeCalled) {
478         frame->addPostCompositeCalled = true;
479         frame->gpuCompositionDoneFence = gpuCompositionDone;
480         mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GPU_COMPOSITION_DONE>();
481         if (!frame->displayPresentFence->isValid()) {
482             frame->displayPresentFence = displayPresent;
483             mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
484         }
485     }
486 }
487 
addRelease(uint64_t frameNumber,nsecs_t dequeueReadyTime,std::shared_ptr<FenceTime> && release)488 void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber,
489         nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) {
490     FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
491     if (frame == nullptr) {
492         ALOGE_IF(mProducerWantsEvents, "addRelease: Did not find frame.");
493         return;
494     }
495     frame->addReleaseCalled = true;
496     frame->dequeueReadyTime = dequeueReadyTime;
497     frame->releaseFence = std::move(release);
498     mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
499 }
500 
getFrameDelta(FrameEventHistoryDelta * delta,const std::vector<FrameEvents>::iterator & frame)501 void ConsumerFrameEventHistory::getFrameDelta(FrameEventHistoryDelta* delta,
502                                               const std::vector<FrameEvents>::iterator& frame) {
503     mProducerWantsEvents = true;
504     size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
505     if (mFramesDirty[i].anyDirty()) {
506         // Make sure only to send back deltas for the current connection
507         // since the producer won't have the correct state to apply a delta
508         // from a previous connection.
509         if (mFrames[i].connectId == mCurrentConnectId) {
510             delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
511         }
512         mFramesDirty[i].reset();
513     }
514 }
515 
getAndResetDelta(FrameEventHistoryDelta * delta)516 void ConsumerFrameEventHistory::getAndResetDelta(
517         FrameEventHistoryDelta* delta) {
518     mProducerWantsEvents = true;
519     delta->mCompositorTiming = mCompositorTiming;
520 
521     // Write these in order of frame number so that it is easy to
522     // add them to a FenceTimeline in the proper order producer side.
523     delta->mDeltas.reserve(mFramesDirty.size());
524     auto earliestFrame = std::min_element(
525             mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
526     for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
527         getFrameDelta(delta, frame);
528     }
529     for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
530         getFrameDelta(delta, frame);
531     }
532 }
533 
resize(size_t newSize)534 void ConsumerFrameEventHistory::resize(size_t newSize) {
535     // we don't want to drop events by resizing too small, so don't resize in the negative direction
536     if (newSize <= mFrames.size()) {
537         return;
538     }
539 
540     // This algorithm for resizing needs to be the same as ProducerFrameEventHistory::resize,
541     // because the indexes need to match when communicating the FrameEventDeltas.
542 
543     // move the existing frame information into a new vector, so that the oldest frames are at
544     // index 0, and the latest frames are towards the end of the vector
545     std::vector<FrameEvents> newFrames(newSize);
546     std::vector<FrameEventDirtyFields> newFramesDirty(newSize);
547     size_t oldestFrameIndex = mQueueOffset;
548     size_t oldI = oldestFrameIndex;
549     size_t newI = 0;
550     do {
551         if (mFrames[oldI].valid) {
552             newFrames[newI] = std::move(mFrames[oldI]);
553             newFramesDirty[newI] = mFramesDirty[oldI];
554             newI += 1;
555         }
556         oldI = (oldI + 1) % mFrames.size();
557     } while (oldI != oldestFrameIndex);
558 
559     mFrames = std::move(newFrames);
560     mFramesDirty = std::move(newFramesDirty);
561     mQueueOffset = newI;
562     mCompositionOffset = 0; // this is just a hint, so setting this to anything is fine
563 }
564 
565 // ============================================================================
566 // FrameEventsDelta
567 // ============================================================================
568 
FrameEventsDelta(size_t index,const FrameEvents & frameTimestamps,const FrameEventDirtyFields & dirtyFields)569 FrameEventsDelta::FrameEventsDelta(
570         size_t index,
571         const FrameEvents& frameTimestamps,
572         const FrameEventDirtyFields& dirtyFields)
573     : mIndex(index),
574       mFrameNumber(frameTimestamps.frameNumber),
575       mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
576       mAddReleaseCalled(frameTimestamps.addReleaseCalled),
577       mPostedTime(frameTimestamps.postedTime),
578       mRequestedPresentTime(frameTimestamps.requestedPresentTime),
579       mLatchTime(frameTimestamps.latchTime),
580       mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
581       mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime),
582       mDequeueReadyTime(frameTimestamps.dequeueReadyTime) {
583     if (dirtyFields.isDirty<FrameEvent::GPU_COMPOSITION_DONE>()) {
584         mGpuCompositionDoneFence =
585                 frameTimestamps.gpuCompositionDoneFence->getSnapshot();
586     }
587     if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
588         mDisplayPresentFence =
589                 frameTimestamps.displayPresentFence->getSnapshot();
590     }
591     if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
592         mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
593     }
594 }
595 
minFlattenedSize()596 constexpr size_t FrameEventsDelta::minFlattenedSize() {
597     return sizeof(FrameEventsDelta::mFrameNumber) +
598             sizeof(uint16_t) + // mIndex
599             sizeof(uint8_t) + // mAddPostCompositeCalled
600             sizeof(uint8_t) + // mAddReleaseCalled
601             sizeof(FrameEventsDelta::mPostedTime) +
602             sizeof(FrameEventsDelta::mRequestedPresentTime) +
603             sizeof(FrameEventsDelta::mLatchTime) +
604             sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
605             sizeof(FrameEventsDelta::mLastRefreshStartTime) +
606             sizeof(FrameEventsDelta::mDequeueReadyTime);
607 }
608 
609 // Flattenable implementation
getFlattenedSize() const610 size_t FrameEventsDelta::getFlattenedSize() const {
611     auto fences = allFences(this);
612     return minFlattenedSize() +
613             std::accumulate(fences.begin(), fences.end(), size_t(0),
614                     [](size_t a, const FenceTime::Snapshot* fence) {
615                             return a + fence->getFlattenedSize();
616                     });
617 }
618 
getFdCount() const619 size_t FrameEventsDelta::getFdCount() const {
620     auto fences = allFences(this);
621     return std::accumulate(fences.begin(), fences.end(), size_t(0),
622             [](size_t a, const FenceTime::Snapshot* fence) {
623                 return a + fence->getFdCount();
624             });
625 }
626 
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const627 status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
628             size_t& count) const {
629     if (size < getFlattenedSize() || count < getFdCount()) {
630         return NO_MEMORY;
631     }
632 
633     if (mIndex >= UINT8_MAX || mIndex < 0) {
634         return BAD_VALUE;
635     }
636 
637     FlattenableUtils::write(buffer, size, mFrameNumber);
638 
639     // These are static_cast to uint16_t/uint8_t for alignment.
640     FlattenableUtils::write(buffer, size, static_cast<uint16_t>(mIndex));
641     FlattenableUtils::write(
642             buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
643     FlattenableUtils::write(
644             buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
645 
646     FlattenableUtils::write(buffer, size, mPostedTime);
647     FlattenableUtils::write(buffer, size, mRequestedPresentTime);
648     FlattenableUtils::write(buffer, size, mLatchTime);
649     FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
650     FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
651     FlattenableUtils::write(buffer, size, mDequeueReadyTime);
652 
653     // Fences
654     for (auto fence : allFences(this)) {
655         status_t status = fence->flatten(buffer, size, fds, count);
656         if (status != NO_ERROR) {
657             return status;
658         }
659     }
660     return NO_ERROR;
661 }
662 
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)663 status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
664             int const*& fds, size_t& count) {
665     if (size < minFlattenedSize()) {
666         return NO_MEMORY;
667     }
668 
669     FlattenableUtils::read(buffer, size, mFrameNumber);
670 
671     // These were written as uint16_t/uint8_t for alignment.
672     uint16_t temp16 = 0;
673     FlattenableUtils::read(buffer, size, temp16);
674     mIndex = temp16;
675     if (mIndex >= UINT8_MAX) {
676         return BAD_VALUE;
677     }
678     uint8_t temp8 = 0;
679     FlattenableUtils::read(buffer, size, temp8);
680     mAddPostCompositeCalled = static_cast<bool>(temp8);
681     FlattenableUtils::read(buffer, size, temp8);
682     mAddReleaseCalled = static_cast<bool>(temp8);
683 
684     FlattenableUtils::read(buffer, size, mPostedTime);
685     FlattenableUtils::read(buffer, size, mRequestedPresentTime);
686     FlattenableUtils::read(buffer, size, mLatchTime);
687     FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
688     FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
689     FlattenableUtils::read(buffer, size, mDequeueReadyTime);
690 
691     // Fences
692     for (auto fence : allFences(this)) {
693         status_t status = fence->unflatten(buffer, size, fds, count);
694         if (status != NO_ERROR) {
695             return status;
696         }
697     }
698     return NO_ERROR;
699 }
700 
getFrameNumber() const701 uint64_t FrameEventsDelta::getFrameNumber() const {
702     return mFrameNumber;
703 }
704 
getLatchTime(nsecs_t * latchTime) const705 bool FrameEventsDelta::getLatchTime(nsecs_t* latchTime) const {
706     if (mLatchTime == FrameEvents::TIMESTAMP_PENDING) {
707         return false;
708     }
709     *latchTime = mLatchTime;
710     return true;
711 }
712 
getDisplayPresentFence(sp<Fence> * fence) const713 bool FrameEventsDelta::getDisplayPresentFence(sp<Fence>* fence) const {
714     if (mDisplayPresentFence.fence == Fence::NO_FENCE) {
715         return false;
716     }
717     *fence = mDisplayPresentFence.fence;
718     return true;
719 }
720 
721 // ============================================================================
722 // FrameEventHistoryDelta
723 // ============================================================================
724 
operator =(FrameEventHistoryDelta && src)725 FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
726         FrameEventHistoryDelta&& src) noexcept {
727     mCompositorTiming = src.mCompositorTiming;
728 
729     if (CC_UNLIKELY(!mDeltas.empty())) {
730         ALOGE("FrameEventHistoryDelta assign clobbering history.");
731     }
732     mDeltas = std::move(src.mDeltas);
733     return *this;
734 }
735 
minFlattenedSize()736 constexpr size_t FrameEventHistoryDelta::minFlattenedSize() {
737     return sizeof(uint32_t) + // mDeltas.size()
738             sizeof(mCompositorTiming);
739 }
740 
getFlattenedSize() const741 size_t FrameEventHistoryDelta::getFlattenedSize() const {
742     return minFlattenedSize() +
743             std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
744                     [](size_t a, const FrameEventsDelta& delta) {
745                             return a + delta.getFlattenedSize();
746                     });
747 }
748 
getFdCount() const749 size_t FrameEventHistoryDelta::getFdCount() const {
750     return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
751             [](size_t a, const FrameEventsDelta& delta) {
752                     return a + delta.getFdCount();
753             });
754 }
755 
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const756 status_t FrameEventHistoryDelta::flatten(
757             void*& buffer, size_t& size, int*& fds, size_t& count) const {
758     if (mDeltas.size() > UINT8_MAX) {
759         return BAD_VALUE;
760     }
761     if (size < getFlattenedSize()) {
762         return NO_MEMORY;
763     }
764 
765     FlattenableUtils::write(buffer, size, mCompositorTiming);
766 
767     FlattenableUtils::write(
768             buffer, size, static_cast<uint32_t>(mDeltas.size()));
769     for (auto& d : mDeltas) {
770         status_t status = d.flatten(buffer, size, fds, count);
771         if (status != NO_ERROR) {
772             return status;
773         }
774     }
775     return NO_ERROR;
776 }
777 
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)778 status_t FrameEventHistoryDelta::unflatten(
779             void const*& buffer, size_t& size, int const*& fds, size_t& count) {
780     if (size < minFlattenedSize()) {
781         return NO_MEMORY;
782     }
783 
784     FlattenableUtils::read(buffer, size, mCompositorTiming);
785 
786     uint32_t deltaCount = 0;
787     FlattenableUtils::read(buffer, size, deltaCount);
788     if (deltaCount > UINT8_MAX) {
789         return BAD_VALUE;
790     }
791     mDeltas.resize(deltaCount);
792     for (auto& d : mDeltas) {
793         status_t status = d.unflatten(buffer, size, fds, count);
794         if (status != NO_ERROR) {
795             return status;
796         }
797     }
798     return NO_ERROR;
799 }
800 
begin() const801 std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::begin() const {
802     return mDeltas.begin();
803 }
804 
end() const805 std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::end() const {
806     return mDeltas.end();
807 }
808 
809 } // namespace android
810