xref: /aosp_15_r20/frameworks/native/libs/gui/FrameTimestamps.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2016 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include <gui/FrameTimestamps.h>
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "FrameEvents"
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker #include <LibGuiProperties.sysprop.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <cutils/compiler.h>  // For CC_[UN]LIKELY
24*38e8c45fSAndroid Build Coastguard Worker #include <inttypes.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <utils/Log.h>
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker #include <algorithm>
28*38e8c45fSAndroid Build Coastguard Worker #include <limits>
29*38e8c45fSAndroid Build Coastguard Worker #include <numeric>
30*38e8c45fSAndroid Build Coastguard Worker 
31*38e8c45fSAndroid Build Coastguard Worker namespace android {
32*38e8c45fSAndroid Build Coastguard Worker 
33*38e8c45fSAndroid Build Coastguard Worker using base::StringAppendF;
34*38e8c45fSAndroid Build Coastguard Worker 
35*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
36*38e8c45fSAndroid Build Coastguard Worker // FrameEvents
37*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
38*38e8c45fSAndroid Build Coastguard Worker 
hasPostedInfo() const39*38e8c45fSAndroid Build Coastguard Worker bool FrameEvents::hasPostedInfo() const {
40*38e8c45fSAndroid Build Coastguard Worker     return FrameEvents::isValidTimestamp(postedTime);
41*38e8c45fSAndroid Build Coastguard Worker }
42*38e8c45fSAndroid Build Coastguard Worker 
hasRequestedPresentInfo() const43*38e8c45fSAndroid Build Coastguard Worker bool FrameEvents::hasRequestedPresentInfo() const {
44*38e8c45fSAndroid Build Coastguard Worker     return FrameEvents::isValidTimestamp(requestedPresentTime);
45*38e8c45fSAndroid Build Coastguard Worker }
46*38e8c45fSAndroid Build Coastguard Worker 
hasLatchInfo() const47*38e8c45fSAndroid Build Coastguard Worker bool FrameEvents::hasLatchInfo() const {
48*38e8c45fSAndroid Build Coastguard Worker     return FrameEvents::isValidTimestamp(latchTime);
49*38e8c45fSAndroid Build Coastguard Worker }
50*38e8c45fSAndroid Build Coastguard Worker 
hasFirstRefreshStartInfo() const51*38e8c45fSAndroid Build Coastguard Worker bool FrameEvents::hasFirstRefreshStartInfo() const {
52*38e8c45fSAndroid Build Coastguard Worker     return FrameEvents::isValidTimestamp(firstRefreshStartTime);
53*38e8c45fSAndroid Build Coastguard Worker }
54*38e8c45fSAndroid Build Coastguard Worker 
hasLastRefreshStartInfo() const55*38e8c45fSAndroid Build Coastguard Worker bool FrameEvents::hasLastRefreshStartInfo() const {
56*38e8c45fSAndroid Build Coastguard Worker     // The last refresh start time may continue to update until a new frame
57*38e8c45fSAndroid Build Coastguard Worker     // is latched. We know we have the final value once the release info is set.
58*38e8c45fSAndroid Build Coastguard Worker     return addReleaseCalled;
59*38e8c45fSAndroid Build Coastguard Worker }
60*38e8c45fSAndroid Build Coastguard Worker 
hasDequeueReadyInfo() const61*38e8c45fSAndroid Build Coastguard Worker bool FrameEvents::hasDequeueReadyInfo() const {
62*38e8c45fSAndroid Build Coastguard Worker     return FrameEvents::isValidTimestamp(dequeueReadyTime);
63*38e8c45fSAndroid Build Coastguard Worker }
64*38e8c45fSAndroid Build Coastguard Worker 
hasAcquireInfo() const65*38e8c45fSAndroid Build Coastguard Worker bool FrameEvents::hasAcquireInfo() const {
66*38e8c45fSAndroid Build Coastguard Worker     return acquireFence->isValid();
67*38e8c45fSAndroid Build Coastguard Worker }
68*38e8c45fSAndroid Build Coastguard Worker 
hasGpuCompositionDoneInfo() const69*38e8c45fSAndroid Build Coastguard Worker bool FrameEvents::hasGpuCompositionDoneInfo() const {
70*38e8c45fSAndroid Build Coastguard Worker     // We may not get a gpuCompositionDone in addPostComposite if
71*38e8c45fSAndroid Build Coastguard Worker     // client/gles compositing isn't needed.
72*38e8c45fSAndroid Build Coastguard Worker     return addPostCompositeCalled;
73*38e8c45fSAndroid Build Coastguard Worker }
74*38e8c45fSAndroid Build Coastguard Worker 
hasDisplayPresentInfo() const75*38e8c45fSAndroid Build Coastguard Worker bool FrameEvents::hasDisplayPresentInfo() const {
76*38e8c45fSAndroid Build Coastguard Worker     // We may not get a displayPresent in addPostComposite for HWC1.
77*38e8c45fSAndroid Build Coastguard Worker     return addPostCompositeCalled;
78*38e8c45fSAndroid Build Coastguard Worker }
79*38e8c45fSAndroid Build Coastguard Worker 
hasReleaseInfo() const80*38e8c45fSAndroid Build Coastguard Worker bool FrameEvents::hasReleaseInfo() const {
81*38e8c45fSAndroid Build Coastguard Worker     return addReleaseCalled;
82*38e8c45fSAndroid Build Coastguard Worker }
83*38e8c45fSAndroid Build Coastguard Worker 
checkFencesForCompletion()84*38e8c45fSAndroid Build Coastguard Worker void FrameEvents::checkFencesForCompletion() {
85*38e8c45fSAndroid Build Coastguard Worker     acquireFence->getSignalTime();
86*38e8c45fSAndroid Build Coastguard Worker     gpuCompositionDoneFence->getSignalTime();
87*38e8c45fSAndroid Build Coastguard Worker     displayPresentFence->getSignalTime();
88*38e8c45fSAndroid Build Coastguard Worker     releaseFence->getSignalTime();
89*38e8c45fSAndroid Build Coastguard Worker }
90*38e8c45fSAndroid Build Coastguard Worker 
dumpFenceTime(std::string & outString,const char * name,bool pending,const FenceTime & fenceTime)91*38e8c45fSAndroid Build Coastguard Worker static void dumpFenceTime(std::string& outString, const char* name, bool pending,
92*38e8c45fSAndroid Build Coastguard Worker                           const FenceTime& fenceTime) {
93*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&outString, "--- %s", name);
94*38e8c45fSAndroid Build Coastguard Worker     nsecs_t signalTime = fenceTime.getCachedSignalTime();
95*38e8c45fSAndroid Build Coastguard Worker     if (Fence::isValidTimestamp(signalTime)) {
96*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&outString, "%" PRId64 "\n", signalTime);
97*38e8c45fSAndroid Build Coastguard Worker     } else if (pending || signalTime == Fence::SIGNAL_TIME_PENDING) {
98*38e8c45fSAndroid Build Coastguard Worker         outString.append("Pending\n");
99*38e8c45fSAndroid Build Coastguard Worker     } else if (&fenceTime == FenceTime::NO_FENCE.get()){
100*38e8c45fSAndroid Build Coastguard Worker         outString.append("N/A\n");
101*38e8c45fSAndroid Build Coastguard Worker     } else {
102*38e8c45fSAndroid Build Coastguard Worker         outString.append("Error\n");
103*38e8c45fSAndroid Build Coastguard Worker     }
104*38e8c45fSAndroid Build Coastguard Worker }
105*38e8c45fSAndroid Build Coastguard Worker 
dump(std::string & outString) const106*38e8c45fSAndroid Build Coastguard Worker void FrameEvents::dump(std::string& outString) const {
107*38e8c45fSAndroid Build Coastguard Worker     if (!valid) {
108*38e8c45fSAndroid Build Coastguard Worker         return;
109*38e8c45fSAndroid Build Coastguard Worker     }
110*38e8c45fSAndroid Build Coastguard Worker 
111*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&outString, "-- Frame %" PRIu64 "\n", frameNumber);
112*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&outString, "--- Posted      \t%" PRId64 "\n", postedTime);
113*38e8c45fSAndroid Build Coastguard Worker     StringAppendF(&outString, "--- Req. Present\t%" PRId64 "\n", requestedPresentTime);
114*38e8c45fSAndroid Build Coastguard Worker 
115*38e8c45fSAndroid Build Coastguard Worker     outString.append("--- Latched     \t");
116*38e8c45fSAndroid Build Coastguard Worker     if (FrameEvents::isValidTimestamp(latchTime)) {
117*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&outString, "%" PRId64 "\n", latchTime);
118*38e8c45fSAndroid Build Coastguard Worker     } else {
119*38e8c45fSAndroid Build Coastguard Worker         outString.append("Pending\n");
120*38e8c45fSAndroid Build Coastguard Worker     }
121*38e8c45fSAndroid Build Coastguard Worker 
122*38e8c45fSAndroid Build Coastguard Worker     outString.append("--- Refresh (First)\t");
123*38e8c45fSAndroid Build Coastguard Worker     if (FrameEvents::isValidTimestamp(firstRefreshStartTime)) {
124*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&outString, "%" PRId64 "\n", firstRefreshStartTime);
125*38e8c45fSAndroid Build Coastguard Worker     } else {
126*38e8c45fSAndroid Build Coastguard Worker         outString.append("Pending\n");
127*38e8c45fSAndroid Build Coastguard Worker     }
128*38e8c45fSAndroid Build Coastguard Worker 
129*38e8c45fSAndroid Build Coastguard Worker     outString.append("--- Refresh (Last)\t");
130*38e8c45fSAndroid Build Coastguard Worker     if (FrameEvents::isValidTimestamp(lastRefreshStartTime)) {
131*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&outString, "%" PRId64 "\n", lastRefreshStartTime);
132*38e8c45fSAndroid Build Coastguard Worker     } else {
133*38e8c45fSAndroid Build Coastguard Worker         outString.append("Pending\n");
134*38e8c45fSAndroid Build Coastguard Worker     }
135*38e8c45fSAndroid Build Coastguard Worker 
136*38e8c45fSAndroid Build Coastguard Worker     dumpFenceTime(outString, "Acquire           \t",
137*38e8c45fSAndroid Build Coastguard Worker             true, *acquireFence);
138*38e8c45fSAndroid Build Coastguard Worker     dumpFenceTime(outString, "GPU Composite Done\t",
139*38e8c45fSAndroid Build Coastguard Worker             !addPostCompositeCalled, *gpuCompositionDoneFence);
140*38e8c45fSAndroid Build Coastguard Worker     dumpFenceTime(outString, "Display Present   \t",
141*38e8c45fSAndroid Build Coastguard Worker             !addPostCompositeCalled, *displayPresentFence);
142*38e8c45fSAndroid Build Coastguard Worker 
143*38e8c45fSAndroid Build Coastguard Worker     outString.append("--- DequeueReady  \t");
144*38e8c45fSAndroid Build Coastguard Worker     if (FrameEvents::isValidTimestamp(dequeueReadyTime)) {
145*38e8c45fSAndroid Build Coastguard Worker         StringAppendF(&outString, "%" PRId64 "\n", dequeueReadyTime);
146*38e8c45fSAndroid Build Coastguard Worker     } else {
147*38e8c45fSAndroid Build Coastguard Worker         outString.append("Pending\n");
148*38e8c45fSAndroid Build Coastguard Worker     }
149*38e8c45fSAndroid Build Coastguard Worker 
150*38e8c45fSAndroid Build Coastguard Worker     dumpFenceTime(outString, "Release           \t",
151*38e8c45fSAndroid Build Coastguard Worker             true, *releaseFence);
152*38e8c45fSAndroid Build Coastguard Worker }
153*38e8c45fSAndroid Build Coastguard Worker 
154*38e8c45fSAndroid Build Coastguard Worker 
155*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
156*38e8c45fSAndroid Build Coastguard Worker // FrameEventHistory
157*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
158*38e8c45fSAndroid Build Coastguard Worker 
159*38e8c45fSAndroid Build Coastguard Worker namespace {
160*38e8c45fSAndroid Build Coastguard Worker 
161*38e8c45fSAndroid Build Coastguard Worker struct FrameNumberEqual {
FrameNumberEqualandroid::__anonb6a4b08b0111::FrameNumberEqual162*38e8c45fSAndroid Build Coastguard Worker     explicit FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
operator ()android::__anonb6a4b08b0111::FrameNumberEqual163*38e8c45fSAndroid Build Coastguard Worker     bool operator()(const FrameEvents& frame) {
164*38e8c45fSAndroid Build Coastguard Worker         return frame.valid && mFrameNumber == frame.frameNumber;
165*38e8c45fSAndroid Build Coastguard Worker     }
166*38e8c45fSAndroid Build Coastguard Worker     const uint64_t mFrameNumber;
167*38e8c45fSAndroid Build Coastguard Worker };
168*38e8c45fSAndroid Build Coastguard Worker 
169*38e8c45fSAndroid Build Coastguard Worker }  // namespace
170*38e8c45fSAndroid Build Coastguard Worker 
171*38e8c45fSAndroid Build Coastguard Worker const size_t FrameEventHistory::INITIAL_MAX_FRAME_HISTORY =
172*38e8c45fSAndroid Build Coastguard Worker         sysprop::LibGuiProperties::frame_event_history_size().value_or(8);
173*38e8c45fSAndroid Build Coastguard Worker 
FrameEventHistory()174*38e8c45fSAndroid Build Coastguard Worker FrameEventHistory::FrameEventHistory()
175*38e8c45fSAndroid Build Coastguard Worker       : mFrames(std::vector<FrameEvents>(INITIAL_MAX_FRAME_HISTORY)) {}
176*38e8c45fSAndroid Build Coastguard Worker 
177*38e8c45fSAndroid Build Coastguard Worker FrameEventHistory::~FrameEventHistory() = default;
178*38e8c45fSAndroid Build Coastguard Worker 
getFrame(uint64_t frameNumber)179*38e8c45fSAndroid Build Coastguard Worker FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber) {
180*38e8c45fSAndroid Build Coastguard Worker     auto frame = std::find_if(
181*38e8c45fSAndroid Build Coastguard Worker             mFrames.begin(), mFrames.end(), FrameNumberEqual(frameNumber));
182*38e8c45fSAndroid Build Coastguard Worker     return frame == mFrames.end() ? nullptr : &(*frame);
183*38e8c45fSAndroid Build Coastguard Worker }
184*38e8c45fSAndroid Build Coastguard Worker 
getFrame(uint64_t frameNumber,size_t * iHint)185*38e8c45fSAndroid Build Coastguard Worker FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber, size_t* iHint) {
186*38e8c45fSAndroid Build Coastguard Worker     *iHint = std::min(*iHint, mFrames.size());
187*38e8c45fSAndroid Build Coastguard Worker     auto hint = mFrames.begin() + *iHint;
188*38e8c45fSAndroid Build Coastguard Worker     auto frame = std::find_if(
189*38e8c45fSAndroid Build Coastguard Worker             hint, mFrames.end(), FrameNumberEqual(frameNumber));
190*38e8c45fSAndroid Build Coastguard Worker     if (frame == mFrames.end()) {
191*38e8c45fSAndroid Build Coastguard Worker         frame = std::find_if(
192*38e8c45fSAndroid Build Coastguard Worker                 mFrames.begin(), hint, FrameNumberEqual(frameNumber));
193*38e8c45fSAndroid Build Coastguard Worker         if (frame == hint) {
194*38e8c45fSAndroid Build Coastguard Worker             return nullptr;
195*38e8c45fSAndroid Build Coastguard Worker         }
196*38e8c45fSAndroid Build Coastguard Worker     }
197*38e8c45fSAndroid Build Coastguard Worker     *iHint = static_cast<size_t>(std::distance(mFrames.begin(), frame));
198*38e8c45fSAndroid Build Coastguard Worker     return &(*frame);
199*38e8c45fSAndroid Build Coastguard Worker }
200*38e8c45fSAndroid Build Coastguard Worker 
checkFencesForCompletion()201*38e8c45fSAndroid Build Coastguard Worker void FrameEventHistory::checkFencesForCompletion() {
202*38e8c45fSAndroid Build Coastguard Worker     for (auto& frame : mFrames) {
203*38e8c45fSAndroid Build Coastguard Worker         frame.checkFencesForCompletion();
204*38e8c45fSAndroid Build Coastguard Worker     }
205*38e8c45fSAndroid Build Coastguard Worker }
206*38e8c45fSAndroid Build Coastguard Worker 
207*38e8c45fSAndroid Build Coastguard Worker // Uses !|valid| as the MSB.
FrameNumberLessThan(const FrameEvents & lhs,const FrameEvents & rhs)208*38e8c45fSAndroid Build Coastguard Worker static bool FrameNumberLessThan(
209*38e8c45fSAndroid Build Coastguard Worker         const FrameEvents& lhs, const FrameEvents& rhs) {
210*38e8c45fSAndroid Build Coastguard Worker     if (lhs.valid == rhs.valid) {
211*38e8c45fSAndroid Build Coastguard Worker         return lhs.frameNumber < rhs.frameNumber;
212*38e8c45fSAndroid Build Coastguard Worker     }
213*38e8c45fSAndroid Build Coastguard Worker     return lhs.valid;
214*38e8c45fSAndroid Build Coastguard Worker }
215*38e8c45fSAndroid Build Coastguard Worker 
dump(std::string & outString) const216*38e8c45fSAndroid Build Coastguard Worker void FrameEventHistory::dump(std::string& outString) const {
217*38e8c45fSAndroid Build Coastguard Worker     auto earliestFrame = std::min_element(
218*38e8c45fSAndroid Build Coastguard Worker             mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
219*38e8c45fSAndroid Build Coastguard Worker     if (!earliestFrame->valid) {
220*38e8c45fSAndroid Build Coastguard Worker         outString.append("-- N/A\n");
221*38e8c45fSAndroid Build Coastguard Worker         return;
222*38e8c45fSAndroid Build Coastguard Worker     }
223*38e8c45fSAndroid Build Coastguard Worker     for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
224*38e8c45fSAndroid Build Coastguard Worker         frame->dump(outString);
225*38e8c45fSAndroid Build Coastguard Worker     }
226*38e8c45fSAndroid Build Coastguard Worker     for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
227*38e8c45fSAndroid Build Coastguard Worker         frame->dump(outString);
228*38e8c45fSAndroid Build Coastguard Worker     }
229*38e8c45fSAndroid Build Coastguard Worker }
230*38e8c45fSAndroid Build Coastguard Worker 
231*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
232*38e8c45fSAndroid Build Coastguard Worker // ProducerFrameEventHistory
233*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
234*38e8c45fSAndroid Build Coastguard Worker 
235*38e8c45fSAndroid Build Coastguard Worker ProducerFrameEventHistory::~ProducerFrameEventHistory() = default;
236*38e8c45fSAndroid Build Coastguard Worker 
snapToNextTick(nsecs_t timestamp,nsecs_t tickPhase,nsecs_t tickInterval)237*38e8c45fSAndroid Build Coastguard Worker nsecs_t ProducerFrameEventHistory::snapToNextTick(
238*38e8c45fSAndroid Build Coastguard Worker         nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval) {
239*38e8c45fSAndroid Build Coastguard Worker     nsecs_t tickOffset = (tickPhase - timestamp) % tickInterval;
240*38e8c45fSAndroid Build Coastguard Worker     // Integer modulo rounds towards 0 and not -inf before taking the remainder,
241*38e8c45fSAndroid Build Coastguard Worker     // so adjust the offset if it is negative.
242*38e8c45fSAndroid Build Coastguard Worker     if (tickOffset < 0) {
243*38e8c45fSAndroid Build Coastguard Worker         tickOffset += tickInterval;
244*38e8c45fSAndroid Build Coastguard Worker     }
245*38e8c45fSAndroid Build Coastguard Worker     return timestamp + tickOffset;
246*38e8c45fSAndroid Build Coastguard Worker }
247*38e8c45fSAndroid Build Coastguard Worker 
getNextCompositeDeadline(const nsecs_t now) const248*38e8c45fSAndroid Build Coastguard Worker nsecs_t ProducerFrameEventHistory::getNextCompositeDeadline(
249*38e8c45fSAndroid Build Coastguard Worker         const nsecs_t now) const{
250*38e8c45fSAndroid Build Coastguard Worker     return snapToNextTick(
251*38e8c45fSAndroid Build Coastguard Worker             now, mCompositorTiming.deadline, mCompositorTiming.interval);
252*38e8c45fSAndroid Build Coastguard Worker }
253*38e8c45fSAndroid Build Coastguard Worker 
updateAcquireFence(uint64_t frameNumber,std::shared_ptr<FenceTime> && acquire)254*38e8c45fSAndroid Build Coastguard Worker void ProducerFrameEventHistory::updateAcquireFence(
255*38e8c45fSAndroid Build Coastguard Worker         uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) {
256*38e8c45fSAndroid Build Coastguard Worker     FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
257*38e8c45fSAndroid Build Coastguard Worker     if (frame == nullptr) {
258*38e8c45fSAndroid Build Coastguard Worker         return;
259*38e8c45fSAndroid Build Coastguard Worker     }
260*38e8c45fSAndroid Build Coastguard Worker 
261*38e8c45fSAndroid Build Coastguard Worker     if (acquire->isValid()) {
262*38e8c45fSAndroid Build Coastguard Worker         mAcquireTimeline.push(acquire);
263*38e8c45fSAndroid Build Coastguard Worker         frame->acquireFence = std::move(acquire);
264*38e8c45fSAndroid Build Coastguard Worker     } else {
265*38e8c45fSAndroid Build Coastguard Worker         // If there isn't an acquire fence, assume that buffer was
266*38e8c45fSAndroid Build Coastguard Worker         // ready for the consumer when posted.
267*38e8c45fSAndroid Build Coastguard Worker         frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
268*38e8c45fSAndroid Build Coastguard Worker     }
269*38e8c45fSAndroid Build Coastguard Worker }
270*38e8c45fSAndroid Build Coastguard Worker 
applyDelta(const FrameEventHistoryDelta & delta)271*38e8c45fSAndroid Build Coastguard Worker void ProducerFrameEventHistory::applyDelta(
272*38e8c45fSAndroid Build Coastguard Worker         const FrameEventHistoryDelta& delta) {
273*38e8c45fSAndroid Build Coastguard Worker     mCompositorTiming = delta.mCompositorTiming;
274*38e8c45fSAndroid Build Coastguard Worker 
275*38e8c45fSAndroid Build Coastguard Worker     // Deltas should have enough reserved capacity for the consumer-side, therefore if there's a
276*38e8c45fSAndroid Build Coastguard Worker     // different capacity, we re-sized on the consumer side and now need to resize on the producer
277*38e8c45fSAndroid Build Coastguard Worker     // side.
278*38e8c45fSAndroid Build Coastguard Worker     if (delta.mDeltas.capacity() > mFrames.capacity()) {
279*38e8c45fSAndroid Build Coastguard Worker         resize(delta.mDeltas.capacity());
280*38e8c45fSAndroid Build Coastguard Worker     }
281*38e8c45fSAndroid Build Coastguard Worker 
282*38e8c45fSAndroid Build Coastguard Worker     for (auto& d : delta.mDeltas) {
283*38e8c45fSAndroid Build Coastguard Worker         // Avoid out-of-bounds access.
284*38e8c45fSAndroid Build Coastguard Worker         if (CC_UNLIKELY(d.mIndex >= mFrames.size())) {
285*38e8c45fSAndroid Build Coastguard Worker             ALOGE("applyDelta: Bad index.");
286*38e8c45fSAndroid Build Coastguard Worker             return;
287*38e8c45fSAndroid Build Coastguard Worker         }
288*38e8c45fSAndroid Build Coastguard Worker 
289*38e8c45fSAndroid Build Coastguard Worker         FrameEvents& frame = mFrames[d.mIndex];
290*38e8c45fSAndroid Build Coastguard Worker 
291*38e8c45fSAndroid Build Coastguard Worker         frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
292*38e8c45fSAndroid Build Coastguard Worker         frame.addReleaseCalled = d.mAddReleaseCalled != 0;
293*38e8c45fSAndroid Build Coastguard Worker 
294*38e8c45fSAndroid Build Coastguard Worker         frame.postedTime = d.mPostedTime;
295*38e8c45fSAndroid Build Coastguard Worker         frame.requestedPresentTime = d.mRequestedPresentTime;
296*38e8c45fSAndroid Build Coastguard Worker         frame.latchTime = d.mLatchTime;
297*38e8c45fSAndroid Build Coastguard Worker         frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
298*38e8c45fSAndroid Build Coastguard Worker         frame.lastRefreshStartTime = d.mLastRefreshStartTime;
299*38e8c45fSAndroid Build Coastguard Worker         frame.dequeueReadyTime = d.mDequeueReadyTime;
300*38e8c45fSAndroid Build Coastguard Worker 
301*38e8c45fSAndroid Build Coastguard Worker         if (frame.frameNumber != d.mFrameNumber) {
302*38e8c45fSAndroid Build Coastguard Worker             // We got a new frame. Initialize some of the fields.
303*38e8c45fSAndroid Build Coastguard Worker             frame.frameNumber = d.mFrameNumber;
304*38e8c45fSAndroid Build Coastguard Worker             frame.acquireFence = FenceTime::NO_FENCE;
305*38e8c45fSAndroid Build Coastguard Worker             frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
306*38e8c45fSAndroid Build Coastguard Worker             frame.displayPresentFence = FenceTime::NO_FENCE;
307*38e8c45fSAndroid Build Coastguard Worker             frame.releaseFence = FenceTime::NO_FENCE;
308*38e8c45fSAndroid Build Coastguard Worker             // The consumer only sends valid frames.
309*38e8c45fSAndroid Build Coastguard Worker             frame.valid = true;
310*38e8c45fSAndroid Build Coastguard Worker         }
311*38e8c45fSAndroid Build Coastguard Worker 
312*38e8c45fSAndroid Build Coastguard Worker         applyFenceDelta(&mGpuCompositionDoneTimeline,
313*38e8c45fSAndroid Build Coastguard Worker                 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
314*38e8c45fSAndroid Build Coastguard Worker         applyFenceDelta(&mPresentTimeline,
315*38e8c45fSAndroid Build Coastguard Worker                 &frame.displayPresentFence, d.mDisplayPresentFence);
316*38e8c45fSAndroid Build Coastguard Worker         applyFenceDelta(&mReleaseTimeline,
317*38e8c45fSAndroid Build Coastguard Worker                 &frame.releaseFence, d.mReleaseFence);
318*38e8c45fSAndroid Build Coastguard Worker     }
319*38e8c45fSAndroid Build Coastguard Worker }
320*38e8c45fSAndroid Build Coastguard Worker 
updateSignalTimes()321*38e8c45fSAndroid Build Coastguard Worker void ProducerFrameEventHistory::updateSignalTimes() {
322*38e8c45fSAndroid Build Coastguard Worker     mAcquireTimeline.updateSignalTimes();
323*38e8c45fSAndroid Build Coastguard Worker     mGpuCompositionDoneTimeline.updateSignalTimes();
324*38e8c45fSAndroid Build Coastguard Worker     mPresentTimeline.updateSignalTimes();
325*38e8c45fSAndroid Build Coastguard Worker     mReleaseTimeline.updateSignalTimes();
326*38e8c45fSAndroid Build Coastguard Worker }
327*38e8c45fSAndroid Build Coastguard Worker 
applyFenceDelta(FenceTimeline * timeline,std::shared_ptr<FenceTime> * dst,const FenceTime::Snapshot & src) const328*38e8c45fSAndroid Build Coastguard Worker void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
329*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
330*38e8c45fSAndroid Build Coastguard Worker     if (CC_UNLIKELY(dst == nullptr || dst->get() == nullptr)) {
331*38e8c45fSAndroid Build Coastguard Worker         ALOGE("applyFenceDelta: dst is null.");
332*38e8c45fSAndroid Build Coastguard Worker         return;
333*38e8c45fSAndroid Build Coastguard Worker     }
334*38e8c45fSAndroid Build Coastguard Worker 
335*38e8c45fSAndroid Build Coastguard Worker     switch (src.state) {
336*38e8c45fSAndroid Build Coastguard Worker         case FenceTime::Snapshot::State::EMPTY:
337*38e8c45fSAndroid Build Coastguard Worker             return;
338*38e8c45fSAndroid Build Coastguard Worker         case FenceTime::Snapshot::State::FENCE:
339*38e8c45fSAndroid Build Coastguard Worker             ALOGE_IF((*dst)->isValid(), "applyFenceDelta: Unexpected fence.");
340*38e8c45fSAndroid Build Coastguard Worker             *dst = createFenceTime(src.fence);
341*38e8c45fSAndroid Build Coastguard Worker             timeline->push(*dst);
342*38e8c45fSAndroid Build Coastguard Worker             return;
343*38e8c45fSAndroid Build Coastguard Worker         case FenceTime::Snapshot::State::SIGNAL_TIME:
344*38e8c45fSAndroid Build Coastguard Worker             if ((*dst)->isValid()) {
345*38e8c45fSAndroid Build Coastguard Worker                 (*dst)->applyTrustedSnapshot(src);
346*38e8c45fSAndroid Build Coastguard Worker             } else {
347*38e8c45fSAndroid Build Coastguard Worker                 *dst = std::make_shared<FenceTime>(src.signalTime);
348*38e8c45fSAndroid Build Coastguard Worker             }
349*38e8c45fSAndroid Build Coastguard Worker             return;
350*38e8c45fSAndroid Build Coastguard Worker     }
351*38e8c45fSAndroid Build Coastguard Worker }
352*38e8c45fSAndroid Build Coastguard Worker 
createFenceTime(const sp<Fence> & fence) const353*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
354*38e8c45fSAndroid Build Coastguard Worker         const sp<Fence>& fence) const {
355*38e8c45fSAndroid Build Coastguard Worker     return std::make_shared<FenceTime>(fence);
356*38e8c45fSAndroid Build Coastguard Worker }
357*38e8c45fSAndroid Build Coastguard Worker 
resize(size_t newSize)358*38e8c45fSAndroid Build Coastguard Worker void ProducerFrameEventHistory::resize(size_t newSize) {
359*38e8c45fSAndroid Build Coastguard Worker     // we don't want to drop events by resizing too small, so don't resize in the negative direction
360*38e8c45fSAndroid Build Coastguard Worker     if (newSize <= mFrames.size()) {
361*38e8c45fSAndroid Build Coastguard Worker         return;
362*38e8c45fSAndroid Build Coastguard Worker     }
363*38e8c45fSAndroid Build Coastguard Worker 
364*38e8c45fSAndroid Build Coastguard Worker     // This algorithm for resizing needs to be the same as ConsumerFrameEventHistory::resize,
365*38e8c45fSAndroid Build Coastguard Worker     // because the indexes need to match when communicating the FrameEventDeltas.
366*38e8c45fSAndroid Build Coastguard Worker 
367*38e8c45fSAndroid Build Coastguard Worker     // We need to find the oldest frame, because that frame needs to move to index 0 in the new
368*38e8c45fSAndroid Build Coastguard Worker     // frame history.
369*38e8c45fSAndroid Build Coastguard Worker     size_t oldestFrameIndex = 0;
370*38e8c45fSAndroid Build Coastguard Worker     size_t oldestFrameNumber = INT32_MAX;
371*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < mFrames.size(); ++i) {
372*38e8c45fSAndroid Build Coastguard Worker         if (mFrames[i].frameNumber < oldestFrameNumber && mFrames[i].valid) {
373*38e8c45fSAndroid Build Coastguard Worker             oldestFrameNumber = mFrames[i].frameNumber;
374*38e8c45fSAndroid Build Coastguard Worker             oldestFrameIndex = i;
375*38e8c45fSAndroid Build Coastguard Worker         }
376*38e8c45fSAndroid Build Coastguard Worker     }
377*38e8c45fSAndroid Build Coastguard Worker 
378*38e8c45fSAndroid Build Coastguard Worker     // move the existing frame information into a new vector, so that the oldest frames are at
379*38e8c45fSAndroid Build Coastguard Worker     // index 0, and the latest frames are at the end of the vector
380*38e8c45fSAndroid Build Coastguard Worker     std::vector<FrameEvents> newFrames(newSize);
381*38e8c45fSAndroid Build Coastguard Worker     size_t oldI = oldestFrameIndex;
382*38e8c45fSAndroid Build Coastguard Worker     size_t newI = 0;
383*38e8c45fSAndroid Build Coastguard Worker     do {
384*38e8c45fSAndroid Build Coastguard Worker         if (mFrames[oldI].valid) {
385*38e8c45fSAndroid Build Coastguard Worker             newFrames[newI++] = std::move(mFrames[oldI]);
386*38e8c45fSAndroid Build Coastguard Worker         }
387*38e8c45fSAndroid Build Coastguard Worker         oldI = (oldI + 1) % mFrames.size();
388*38e8c45fSAndroid Build Coastguard Worker     } while (oldI != oldestFrameIndex);
389*38e8c45fSAndroid Build Coastguard Worker 
390*38e8c45fSAndroid Build Coastguard Worker     mFrames = std::move(newFrames);
391*38e8c45fSAndroid Build Coastguard Worker     mAcquireOffset = 0; // this is just a hint, so setting this to anything is fine
392*38e8c45fSAndroid Build Coastguard Worker }
393*38e8c45fSAndroid Build Coastguard Worker 
394*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
395*38e8c45fSAndroid Build Coastguard Worker // ConsumerFrameEventHistory
396*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
397*38e8c45fSAndroid Build Coastguard Worker 
ConsumerFrameEventHistory()398*38e8c45fSAndroid Build Coastguard Worker ConsumerFrameEventHistory::ConsumerFrameEventHistory()
399*38e8c45fSAndroid Build Coastguard Worker       : mFramesDirty(std::vector<FrameEventDirtyFields>(INITIAL_MAX_FRAME_HISTORY)) {}
400*38e8c45fSAndroid Build Coastguard Worker 
401*38e8c45fSAndroid Build Coastguard Worker ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
402*38e8c45fSAndroid Build Coastguard Worker 
onDisconnect()403*38e8c45fSAndroid Build Coastguard Worker void ConsumerFrameEventHistory::onDisconnect() {
404*38e8c45fSAndroid Build Coastguard Worker     mCurrentConnectId++;
405*38e8c45fSAndroid Build Coastguard Worker     mProducerWantsEvents = false;
406*38e8c45fSAndroid Build Coastguard Worker }
407*38e8c45fSAndroid Build Coastguard Worker 
setProducerWantsEvents()408*38e8c45fSAndroid Build Coastguard Worker void ConsumerFrameEventHistory::setProducerWantsEvents() {
409*38e8c45fSAndroid Build Coastguard Worker     mProducerWantsEvents = true;
410*38e8c45fSAndroid Build Coastguard Worker }
411*38e8c45fSAndroid Build Coastguard Worker 
initializeCompositorTiming(const CompositorTiming & compositorTiming)412*38e8c45fSAndroid Build Coastguard Worker void ConsumerFrameEventHistory::initializeCompositorTiming(
413*38e8c45fSAndroid Build Coastguard Worker         const CompositorTiming& compositorTiming) {
414*38e8c45fSAndroid Build Coastguard Worker     mCompositorTiming = compositorTiming;
415*38e8c45fSAndroid Build Coastguard Worker }
416*38e8c45fSAndroid Build Coastguard Worker 
addQueue(const NewFrameEventsEntry & newEntry)417*38e8c45fSAndroid Build Coastguard Worker void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
418*38e8c45fSAndroid Build Coastguard Worker     // Overwrite all fields of the frame with default values unless set here.
419*38e8c45fSAndroid Build Coastguard Worker     FrameEvents newTimestamps;
420*38e8c45fSAndroid Build Coastguard Worker     newTimestamps.connectId = mCurrentConnectId;
421*38e8c45fSAndroid Build Coastguard Worker     newTimestamps.frameNumber = newEntry.frameNumber;
422*38e8c45fSAndroid Build Coastguard Worker     newTimestamps.postedTime = newEntry.postedTime;
423*38e8c45fSAndroid Build Coastguard Worker     newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
424*38e8c45fSAndroid Build Coastguard Worker     newTimestamps.acquireFence = newEntry.acquireFence;
425*38e8c45fSAndroid Build Coastguard Worker     newTimestamps.valid = true;
426*38e8c45fSAndroid Build Coastguard Worker     mFrames[mQueueOffset] = newTimestamps;
427*38e8c45fSAndroid Build Coastguard Worker 
428*38e8c45fSAndroid Build Coastguard Worker     // Note: We avoid sending the acquire fence back to the caller since
429*38e8c45fSAndroid Build Coastguard Worker     // they have the original one already, so there is no need to set the
430*38e8c45fSAndroid Build Coastguard Worker     // acquire dirty bit.
431*38e8c45fSAndroid Build Coastguard Worker     mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
432*38e8c45fSAndroid Build Coastguard Worker 
433*38e8c45fSAndroid Build Coastguard Worker     mQueueOffset = (mQueueOffset + 1) % mFrames.size();
434*38e8c45fSAndroid Build Coastguard Worker }
435*38e8c45fSAndroid Build Coastguard Worker 
addLatch(uint64_t frameNumber,nsecs_t latchTime)436*38e8c45fSAndroid Build Coastguard Worker void ConsumerFrameEventHistory::addLatch(
437*38e8c45fSAndroid Build Coastguard Worker         uint64_t frameNumber, nsecs_t latchTime) {
438*38e8c45fSAndroid Build Coastguard Worker     FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
439*38e8c45fSAndroid Build Coastguard Worker     if (frame == nullptr) {
440*38e8c45fSAndroid Build Coastguard Worker         ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
441*38e8c45fSAndroid Build Coastguard Worker         return;
442*38e8c45fSAndroid Build Coastguard Worker     }
443*38e8c45fSAndroid Build Coastguard Worker     frame->latchTime = latchTime;
444*38e8c45fSAndroid Build Coastguard Worker     mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
445*38e8c45fSAndroid Build Coastguard Worker }
446*38e8c45fSAndroid Build Coastguard Worker 
addPreComposition(uint64_t frameNumber,nsecs_t refreshStartTime)447*38e8c45fSAndroid Build Coastguard Worker void ConsumerFrameEventHistory::addPreComposition(
448*38e8c45fSAndroid Build Coastguard Worker         uint64_t frameNumber, nsecs_t refreshStartTime) {
449*38e8c45fSAndroid Build Coastguard Worker     FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
450*38e8c45fSAndroid Build Coastguard Worker     if (frame == nullptr) {
451*38e8c45fSAndroid Build Coastguard Worker         ALOGE_IF(mProducerWantsEvents,
452*38e8c45fSAndroid Build Coastguard Worker                 "addPreComposition: Did not find frame.");
453*38e8c45fSAndroid Build Coastguard Worker         return;
454*38e8c45fSAndroid Build Coastguard Worker     }
455*38e8c45fSAndroid Build Coastguard Worker     frame->lastRefreshStartTime = refreshStartTime;
456*38e8c45fSAndroid Build Coastguard Worker     mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
457*38e8c45fSAndroid Build Coastguard Worker     if (!FrameEvents::isValidTimestamp(frame->firstRefreshStartTime)) {
458*38e8c45fSAndroid Build Coastguard Worker         frame->firstRefreshStartTime = refreshStartTime;
459*38e8c45fSAndroid Build Coastguard Worker         mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
460*38e8c45fSAndroid Build Coastguard Worker     }
461*38e8c45fSAndroid Build Coastguard Worker }
462*38e8c45fSAndroid Build Coastguard Worker 
addPostComposition(uint64_t frameNumber,const std::shared_ptr<FenceTime> & gpuCompositionDone,const std::shared_ptr<FenceTime> & displayPresent,const CompositorTiming & compositorTiming)463*38e8c45fSAndroid Build Coastguard Worker void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
464*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<FenceTime>& gpuCompositionDone,
465*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<FenceTime>& displayPresent,
466*38e8c45fSAndroid Build Coastguard Worker         const CompositorTiming& compositorTiming) {
467*38e8c45fSAndroid Build Coastguard Worker     mCompositorTiming = compositorTiming;
468*38e8c45fSAndroid Build Coastguard Worker 
469*38e8c45fSAndroid Build Coastguard Worker     FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
470*38e8c45fSAndroid Build Coastguard Worker     if (frame == nullptr) {
471*38e8c45fSAndroid Build Coastguard Worker         ALOGE_IF(mProducerWantsEvents,
472*38e8c45fSAndroid Build Coastguard Worker                 "addPostComposition: Did not find frame.");
473*38e8c45fSAndroid Build Coastguard Worker         return;
474*38e8c45fSAndroid Build Coastguard Worker     }
475*38e8c45fSAndroid Build Coastguard Worker     // Only get GPU and present info for the first composite.
476*38e8c45fSAndroid Build Coastguard Worker     if (!frame->addPostCompositeCalled) {
477*38e8c45fSAndroid Build Coastguard Worker         frame->addPostCompositeCalled = true;
478*38e8c45fSAndroid Build Coastguard Worker         frame->gpuCompositionDoneFence = gpuCompositionDone;
479*38e8c45fSAndroid Build Coastguard Worker         mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GPU_COMPOSITION_DONE>();
480*38e8c45fSAndroid Build Coastguard Worker         if (!frame->displayPresentFence->isValid()) {
481*38e8c45fSAndroid Build Coastguard Worker             frame->displayPresentFence = displayPresent;
482*38e8c45fSAndroid Build Coastguard Worker             mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
483*38e8c45fSAndroid Build Coastguard Worker         }
484*38e8c45fSAndroid Build Coastguard Worker     }
485*38e8c45fSAndroid Build Coastguard Worker }
486*38e8c45fSAndroid Build Coastguard Worker 
addRelease(uint64_t frameNumber,nsecs_t dequeueReadyTime,std::shared_ptr<FenceTime> && release)487*38e8c45fSAndroid Build Coastguard Worker void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber,
488*38e8c45fSAndroid Build Coastguard Worker         nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) {
489*38e8c45fSAndroid Build Coastguard Worker     FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
490*38e8c45fSAndroid Build Coastguard Worker     if (frame == nullptr) {
491*38e8c45fSAndroid Build Coastguard Worker         ALOGE_IF(mProducerWantsEvents, "addRelease: Did not find frame.");
492*38e8c45fSAndroid Build Coastguard Worker         return;
493*38e8c45fSAndroid Build Coastguard Worker     }
494*38e8c45fSAndroid Build Coastguard Worker     frame->addReleaseCalled = true;
495*38e8c45fSAndroid Build Coastguard Worker     frame->dequeueReadyTime = dequeueReadyTime;
496*38e8c45fSAndroid Build Coastguard Worker     frame->releaseFence = std::move(release);
497*38e8c45fSAndroid Build Coastguard Worker     mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
498*38e8c45fSAndroid Build Coastguard Worker }
499*38e8c45fSAndroid Build Coastguard Worker 
getFrameDelta(FrameEventHistoryDelta * delta,const std::vector<FrameEvents>::iterator & frame)500*38e8c45fSAndroid Build Coastguard Worker void ConsumerFrameEventHistory::getFrameDelta(FrameEventHistoryDelta* delta,
501*38e8c45fSAndroid Build Coastguard Worker                                               const std::vector<FrameEvents>::iterator& frame) {
502*38e8c45fSAndroid Build Coastguard Worker     mProducerWantsEvents = true;
503*38e8c45fSAndroid Build Coastguard Worker     size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
504*38e8c45fSAndroid Build Coastguard Worker     if (mFramesDirty[i].anyDirty()) {
505*38e8c45fSAndroid Build Coastguard Worker         // Make sure only to send back deltas for the current connection
506*38e8c45fSAndroid Build Coastguard Worker         // since the producer won't have the correct state to apply a delta
507*38e8c45fSAndroid Build Coastguard Worker         // from a previous connection.
508*38e8c45fSAndroid Build Coastguard Worker         if (mFrames[i].connectId == mCurrentConnectId) {
509*38e8c45fSAndroid Build Coastguard Worker             delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
510*38e8c45fSAndroid Build Coastguard Worker         }
511*38e8c45fSAndroid Build Coastguard Worker         mFramesDirty[i].reset();
512*38e8c45fSAndroid Build Coastguard Worker     }
513*38e8c45fSAndroid Build Coastguard Worker }
514*38e8c45fSAndroid Build Coastguard Worker 
getAndResetDelta(FrameEventHistoryDelta * delta)515*38e8c45fSAndroid Build Coastguard Worker void ConsumerFrameEventHistory::getAndResetDelta(
516*38e8c45fSAndroid Build Coastguard Worker         FrameEventHistoryDelta* delta) {
517*38e8c45fSAndroid Build Coastguard Worker     mProducerWantsEvents = true;
518*38e8c45fSAndroid Build Coastguard Worker     delta->mCompositorTiming = mCompositorTiming;
519*38e8c45fSAndroid Build Coastguard Worker 
520*38e8c45fSAndroid Build Coastguard Worker     // Write these in order of frame number so that it is easy to
521*38e8c45fSAndroid Build Coastguard Worker     // add them to a FenceTimeline in the proper order producer side.
522*38e8c45fSAndroid Build Coastguard Worker     delta->mDeltas.reserve(mFramesDirty.size());
523*38e8c45fSAndroid Build Coastguard Worker     auto earliestFrame = std::min_element(
524*38e8c45fSAndroid Build Coastguard Worker             mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
525*38e8c45fSAndroid Build Coastguard Worker     for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
526*38e8c45fSAndroid Build Coastguard Worker         getFrameDelta(delta, frame);
527*38e8c45fSAndroid Build Coastguard Worker     }
528*38e8c45fSAndroid Build Coastguard Worker     for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
529*38e8c45fSAndroid Build Coastguard Worker         getFrameDelta(delta, frame);
530*38e8c45fSAndroid Build Coastguard Worker     }
531*38e8c45fSAndroid Build Coastguard Worker }
532*38e8c45fSAndroid Build Coastguard Worker 
resize(size_t newSize)533*38e8c45fSAndroid Build Coastguard Worker void ConsumerFrameEventHistory::resize(size_t newSize) {
534*38e8c45fSAndroid Build Coastguard Worker     // we don't want to drop events by resizing too small, so don't resize in the negative direction
535*38e8c45fSAndroid Build Coastguard Worker     if (newSize <= mFrames.size()) {
536*38e8c45fSAndroid Build Coastguard Worker         return;
537*38e8c45fSAndroid Build Coastguard Worker     }
538*38e8c45fSAndroid Build Coastguard Worker 
539*38e8c45fSAndroid Build Coastguard Worker     // This algorithm for resizing needs to be the same as ProducerFrameEventHistory::resize,
540*38e8c45fSAndroid Build Coastguard Worker     // because the indexes need to match when communicating the FrameEventDeltas.
541*38e8c45fSAndroid Build Coastguard Worker 
542*38e8c45fSAndroid Build Coastguard Worker     // move the existing frame information into a new vector, so that the oldest frames are at
543*38e8c45fSAndroid Build Coastguard Worker     // index 0, and the latest frames are towards the end of the vector
544*38e8c45fSAndroid Build Coastguard Worker     std::vector<FrameEvents> newFrames(newSize);
545*38e8c45fSAndroid Build Coastguard Worker     std::vector<FrameEventDirtyFields> newFramesDirty(newSize);
546*38e8c45fSAndroid Build Coastguard Worker     size_t oldestFrameIndex = mQueueOffset;
547*38e8c45fSAndroid Build Coastguard Worker     size_t oldI = oldestFrameIndex;
548*38e8c45fSAndroid Build Coastguard Worker     size_t newI = 0;
549*38e8c45fSAndroid Build Coastguard Worker     do {
550*38e8c45fSAndroid Build Coastguard Worker         if (mFrames[oldI].valid) {
551*38e8c45fSAndroid Build Coastguard Worker             newFrames[newI] = std::move(mFrames[oldI]);
552*38e8c45fSAndroid Build Coastguard Worker             newFramesDirty[newI] = mFramesDirty[oldI];
553*38e8c45fSAndroid Build Coastguard Worker             newI += 1;
554*38e8c45fSAndroid Build Coastguard Worker         }
555*38e8c45fSAndroid Build Coastguard Worker         oldI = (oldI + 1) % mFrames.size();
556*38e8c45fSAndroid Build Coastguard Worker     } while (oldI != oldestFrameIndex);
557*38e8c45fSAndroid Build Coastguard Worker 
558*38e8c45fSAndroid Build Coastguard Worker     mFrames = std::move(newFrames);
559*38e8c45fSAndroid Build Coastguard Worker     mFramesDirty = std::move(newFramesDirty);
560*38e8c45fSAndroid Build Coastguard Worker     mQueueOffset = newI;
561*38e8c45fSAndroid Build Coastguard Worker     mCompositionOffset = 0; // this is just a hint, so setting this to anything is fine
562*38e8c45fSAndroid Build Coastguard Worker }
563*38e8c45fSAndroid Build Coastguard Worker 
564*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
565*38e8c45fSAndroid Build Coastguard Worker // FrameEventsDelta
566*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
567*38e8c45fSAndroid Build Coastguard Worker 
FrameEventsDelta(size_t index,const FrameEvents & frameTimestamps,const FrameEventDirtyFields & dirtyFields)568*38e8c45fSAndroid Build Coastguard Worker FrameEventsDelta::FrameEventsDelta(
569*38e8c45fSAndroid Build Coastguard Worker         size_t index,
570*38e8c45fSAndroid Build Coastguard Worker         const FrameEvents& frameTimestamps,
571*38e8c45fSAndroid Build Coastguard Worker         const FrameEventDirtyFields& dirtyFields)
572*38e8c45fSAndroid Build Coastguard Worker     : mIndex(index),
573*38e8c45fSAndroid Build Coastguard Worker       mFrameNumber(frameTimestamps.frameNumber),
574*38e8c45fSAndroid Build Coastguard Worker       mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
575*38e8c45fSAndroid Build Coastguard Worker       mAddReleaseCalled(frameTimestamps.addReleaseCalled),
576*38e8c45fSAndroid Build Coastguard Worker       mPostedTime(frameTimestamps.postedTime),
577*38e8c45fSAndroid Build Coastguard Worker       mRequestedPresentTime(frameTimestamps.requestedPresentTime),
578*38e8c45fSAndroid Build Coastguard Worker       mLatchTime(frameTimestamps.latchTime),
579*38e8c45fSAndroid Build Coastguard Worker       mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
580*38e8c45fSAndroid Build Coastguard Worker       mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime),
581*38e8c45fSAndroid Build Coastguard Worker       mDequeueReadyTime(frameTimestamps.dequeueReadyTime) {
582*38e8c45fSAndroid Build Coastguard Worker     if (dirtyFields.isDirty<FrameEvent::GPU_COMPOSITION_DONE>()) {
583*38e8c45fSAndroid Build Coastguard Worker         mGpuCompositionDoneFence =
584*38e8c45fSAndroid Build Coastguard Worker                 frameTimestamps.gpuCompositionDoneFence->getSnapshot();
585*38e8c45fSAndroid Build Coastguard Worker     }
586*38e8c45fSAndroid Build Coastguard Worker     if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
587*38e8c45fSAndroid Build Coastguard Worker         mDisplayPresentFence =
588*38e8c45fSAndroid Build Coastguard Worker                 frameTimestamps.displayPresentFence->getSnapshot();
589*38e8c45fSAndroid Build Coastguard Worker     }
590*38e8c45fSAndroid Build Coastguard Worker     if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
591*38e8c45fSAndroid Build Coastguard Worker         mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
592*38e8c45fSAndroid Build Coastguard Worker     }
593*38e8c45fSAndroid Build Coastguard Worker }
594*38e8c45fSAndroid Build Coastguard Worker 
minFlattenedSize()595*38e8c45fSAndroid Build Coastguard Worker constexpr size_t FrameEventsDelta::minFlattenedSize() {
596*38e8c45fSAndroid Build Coastguard Worker     return sizeof(FrameEventsDelta::mFrameNumber) +
597*38e8c45fSAndroid Build Coastguard Worker             sizeof(uint16_t) + // mIndex
598*38e8c45fSAndroid Build Coastguard Worker             sizeof(uint8_t) + // mAddPostCompositeCalled
599*38e8c45fSAndroid Build Coastguard Worker             sizeof(uint8_t) + // mAddReleaseCalled
600*38e8c45fSAndroid Build Coastguard Worker             sizeof(FrameEventsDelta::mPostedTime) +
601*38e8c45fSAndroid Build Coastguard Worker             sizeof(FrameEventsDelta::mRequestedPresentTime) +
602*38e8c45fSAndroid Build Coastguard Worker             sizeof(FrameEventsDelta::mLatchTime) +
603*38e8c45fSAndroid Build Coastguard Worker             sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
604*38e8c45fSAndroid Build Coastguard Worker             sizeof(FrameEventsDelta::mLastRefreshStartTime) +
605*38e8c45fSAndroid Build Coastguard Worker             sizeof(FrameEventsDelta::mDequeueReadyTime);
606*38e8c45fSAndroid Build Coastguard Worker }
607*38e8c45fSAndroid Build Coastguard Worker 
608*38e8c45fSAndroid Build Coastguard Worker // Flattenable implementation
getFlattenedSize() const609*38e8c45fSAndroid Build Coastguard Worker size_t FrameEventsDelta::getFlattenedSize() const {
610*38e8c45fSAndroid Build Coastguard Worker     auto fences = allFences(this);
611*38e8c45fSAndroid Build Coastguard Worker     return minFlattenedSize() +
612*38e8c45fSAndroid Build Coastguard Worker             std::accumulate(fences.begin(), fences.end(), size_t(0),
613*38e8c45fSAndroid Build Coastguard Worker                     [](size_t a, const FenceTime::Snapshot* fence) {
614*38e8c45fSAndroid Build Coastguard Worker                             return a + fence->getFlattenedSize();
615*38e8c45fSAndroid Build Coastguard Worker                     });
616*38e8c45fSAndroid Build Coastguard Worker }
617*38e8c45fSAndroid Build Coastguard Worker 
getFdCount() const618*38e8c45fSAndroid Build Coastguard Worker size_t FrameEventsDelta::getFdCount() const {
619*38e8c45fSAndroid Build Coastguard Worker     auto fences = allFences(this);
620*38e8c45fSAndroid Build Coastguard Worker     return std::accumulate(fences.begin(), fences.end(), size_t(0),
621*38e8c45fSAndroid Build Coastguard Worker             [](size_t a, const FenceTime::Snapshot* fence) {
622*38e8c45fSAndroid Build Coastguard Worker                 return a + fence->getFdCount();
623*38e8c45fSAndroid Build Coastguard Worker             });
624*38e8c45fSAndroid Build Coastguard Worker }
625*38e8c45fSAndroid Build Coastguard Worker 
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const626*38e8c45fSAndroid Build Coastguard Worker status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
627*38e8c45fSAndroid Build Coastguard Worker             size_t& count) const {
628*38e8c45fSAndroid Build Coastguard Worker     if (size < getFlattenedSize() || count < getFdCount()) {
629*38e8c45fSAndroid Build Coastguard Worker         return NO_MEMORY;
630*38e8c45fSAndroid Build Coastguard Worker     }
631*38e8c45fSAndroid Build Coastguard Worker 
632*38e8c45fSAndroid Build Coastguard Worker     if (mIndex >= UINT8_MAX || mIndex < 0) {
633*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
634*38e8c45fSAndroid Build Coastguard Worker     }
635*38e8c45fSAndroid Build Coastguard Worker 
636*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(buffer, size, mFrameNumber);
637*38e8c45fSAndroid Build Coastguard Worker 
638*38e8c45fSAndroid Build Coastguard Worker     // These are static_cast to uint16_t/uint8_t for alignment.
639*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(buffer, size, static_cast<uint16_t>(mIndex));
640*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(
641*38e8c45fSAndroid Build Coastguard Worker             buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
642*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(
643*38e8c45fSAndroid Build Coastguard Worker             buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
644*38e8c45fSAndroid Build Coastguard Worker 
645*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(buffer, size, mPostedTime);
646*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(buffer, size, mRequestedPresentTime);
647*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(buffer, size, mLatchTime);
648*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
649*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
650*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(buffer, size, mDequeueReadyTime);
651*38e8c45fSAndroid Build Coastguard Worker 
652*38e8c45fSAndroid Build Coastguard Worker     // Fences
653*38e8c45fSAndroid Build Coastguard Worker     for (auto fence : allFences(this)) {
654*38e8c45fSAndroid Build Coastguard Worker         status_t status = fence->flatten(buffer, size, fds, count);
655*38e8c45fSAndroid Build Coastguard Worker         if (status != NO_ERROR) {
656*38e8c45fSAndroid Build Coastguard Worker             return status;
657*38e8c45fSAndroid Build Coastguard Worker         }
658*38e8c45fSAndroid Build Coastguard Worker     }
659*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
660*38e8c45fSAndroid Build Coastguard Worker }
661*38e8c45fSAndroid Build Coastguard Worker 
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)662*38e8c45fSAndroid Build Coastguard Worker status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
663*38e8c45fSAndroid Build Coastguard Worker             int const*& fds, size_t& count) {
664*38e8c45fSAndroid Build Coastguard Worker     if (size < minFlattenedSize()) {
665*38e8c45fSAndroid Build Coastguard Worker         return NO_MEMORY;
666*38e8c45fSAndroid Build Coastguard Worker     }
667*38e8c45fSAndroid Build Coastguard Worker 
668*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, mFrameNumber);
669*38e8c45fSAndroid Build Coastguard Worker 
670*38e8c45fSAndroid Build Coastguard Worker     // These were written as uint16_t/uint8_t for alignment.
671*38e8c45fSAndroid Build Coastguard Worker     uint16_t temp16 = 0;
672*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, temp16);
673*38e8c45fSAndroid Build Coastguard Worker     mIndex = temp16;
674*38e8c45fSAndroid Build Coastguard Worker     if (mIndex >= UINT8_MAX) {
675*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
676*38e8c45fSAndroid Build Coastguard Worker     }
677*38e8c45fSAndroid Build Coastguard Worker     uint8_t temp8 = 0;
678*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, temp8);
679*38e8c45fSAndroid Build Coastguard Worker     mAddPostCompositeCalled = static_cast<bool>(temp8);
680*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, temp8);
681*38e8c45fSAndroid Build Coastguard Worker     mAddReleaseCalled = static_cast<bool>(temp8);
682*38e8c45fSAndroid Build Coastguard Worker 
683*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, mPostedTime);
684*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, mRequestedPresentTime);
685*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, mLatchTime);
686*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
687*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
688*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, mDequeueReadyTime);
689*38e8c45fSAndroid Build Coastguard Worker 
690*38e8c45fSAndroid Build Coastguard Worker     // Fences
691*38e8c45fSAndroid Build Coastguard Worker     for (auto fence : allFences(this)) {
692*38e8c45fSAndroid Build Coastguard Worker         status_t status = fence->unflatten(buffer, size, fds, count);
693*38e8c45fSAndroid Build Coastguard Worker         if (status != NO_ERROR) {
694*38e8c45fSAndroid Build Coastguard Worker             return status;
695*38e8c45fSAndroid Build Coastguard Worker         }
696*38e8c45fSAndroid Build Coastguard Worker     }
697*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
698*38e8c45fSAndroid Build Coastguard Worker }
699*38e8c45fSAndroid Build Coastguard Worker 
getFrameNumber() const700*38e8c45fSAndroid Build Coastguard Worker uint64_t FrameEventsDelta::getFrameNumber() const {
701*38e8c45fSAndroid Build Coastguard Worker     return mFrameNumber;
702*38e8c45fSAndroid Build Coastguard Worker }
703*38e8c45fSAndroid Build Coastguard Worker 
getLatchTime(nsecs_t * latchTime) const704*38e8c45fSAndroid Build Coastguard Worker bool FrameEventsDelta::getLatchTime(nsecs_t* latchTime) const {
705*38e8c45fSAndroid Build Coastguard Worker     if (mLatchTime == FrameEvents::TIMESTAMP_PENDING) {
706*38e8c45fSAndroid Build Coastguard Worker         return false;
707*38e8c45fSAndroid Build Coastguard Worker     }
708*38e8c45fSAndroid Build Coastguard Worker     *latchTime = mLatchTime;
709*38e8c45fSAndroid Build Coastguard Worker     return true;
710*38e8c45fSAndroid Build Coastguard Worker }
711*38e8c45fSAndroid Build Coastguard Worker 
getDisplayPresentFence(sp<Fence> * fence) const712*38e8c45fSAndroid Build Coastguard Worker bool FrameEventsDelta::getDisplayPresentFence(sp<Fence>* fence) const {
713*38e8c45fSAndroid Build Coastguard Worker     if (mDisplayPresentFence.fence == Fence::NO_FENCE) {
714*38e8c45fSAndroid Build Coastguard Worker         return false;
715*38e8c45fSAndroid Build Coastguard Worker     }
716*38e8c45fSAndroid Build Coastguard Worker     *fence = mDisplayPresentFence.fence;
717*38e8c45fSAndroid Build Coastguard Worker     return true;
718*38e8c45fSAndroid Build Coastguard Worker }
719*38e8c45fSAndroid Build Coastguard Worker 
720*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
721*38e8c45fSAndroid Build Coastguard Worker // FrameEventHistoryDelta
722*38e8c45fSAndroid Build Coastguard Worker // ============================================================================
723*38e8c45fSAndroid Build Coastguard Worker 
operator =(FrameEventHistoryDelta && src)724*38e8c45fSAndroid Build Coastguard Worker FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
725*38e8c45fSAndroid Build Coastguard Worker         FrameEventHistoryDelta&& src) noexcept {
726*38e8c45fSAndroid Build Coastguard Worker     mCompositorTiming = src.mCompositorTiming;
727*38e8c45fSAndroid Build Coastguard Worker 
728*38e8c45fSAndroid Build Coastguard Worker     if (CC_UNLIKELY(!mDeltas.empty())) {
729*38e8c45fSAndroid Build Coastguard Worker         ALOGE("FrameEventHistoryDelta assign clobbering history.");
730*38e8c45fSAndroid Build Coastguard Worker     }
731*38e8c45fSAndroid Build Coastguard Worker     mDeltas = std::move(src.mDeltas);
732*38e8c45fSAndroid Build Coastguard Worker     return *this;
733*38e8c45fSAndroid Build Coastguard Worker }
734*38e8c45fSAndroid Build Coastguard Worker 
minFlattenedSize()735*38e8c45fSAndroid Build Coastguard Worker constexpr size_t FrameEventHistoryDelta::minFlattenedSize() {
736*38e8c45fSAndroid Build Coastguard Worker     return sizeof(uint32_t) + // mDeltas.size()
737*38e8c45fSAndroid Build Coastguard Worker             sizeof(mCompositorTiming);
738*38e8c45fSAndroid Build Coastguard Worker }
739*38e8c45fSAndroid Build Coastguard Worker 
getFlattenedSize() const740*38e8c45fSAndroid Build Coastguard Worker size_t FrameEventHistoryDelta::getFlattenedSize() const {
741*38e8c45fSAndroid Build Coastguard Worker     return minFlattenedSize() +
742*38e8c45fSAndroid Build Coastguard Worker             std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
743*38e8c45fSAndroid Build Coastguard Worker                     [](size_t a, const FrameEventsDelta& delta) {
744*38e8c45fSAndroid Build Coastguard Worker                             return a + delta.getFlattenedSize();
745*38e8c45fSAndroid Build Coastguard Worker                     });
746*38e8c45fSAndroid Build Coastguard Worker }
747*38e8c45fSAndroid Build Coastguard Worker 
getFdCount() const748*38e8c45fSAndroid Build Coastguard Worker size_t FrameEventHistoryDelta::getFdCount() const {
749*38e8c45fSAndroid Build Coastguard Worker     return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
750*38e8c45fSAndroid Build Coastguard Worker             [](size_t a, const FrameEventsDelta& delta) {
751*38e8c45fSAndroid Build Coastguard Worker                     return a + delta.getFdCount();
752*38e8c45fSAndroid Build Coastguard Worker             });
753*38e8c45fSAndroid Build Coastguard Worker }
754*38e8c45fSAndroid Build Coastguard Worker 
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const755*38e8c45fSAndroid Build Coastguard Worker status_t FrameEventHistoryDelta::flatten(
756*38e8c45fSAndroid Build Coastguard Worker             void*& buffer, size_t& size, int*& fds, size_t& count) const {
757*38e8c45fSAndroid Build Coastguard Worker     if (mDeltas.size() > UINT8_MAX) {
758*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
759*38e8c45fSAndroid Build Coastguard Worker     }
760*38e8c45fSAndroid Build Coastguard Worker     if (size < getFlattenedSize()) {
761*38e8c45fSAndroid Build Coastguard Worker         return NO_MEMORY;
762*38e8c45fSAndroid Build Coastguard Worker     }
763*38e8c45fSAndroid Build Coastguard Worker 
764*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(buffer, size, mCompositorTiming);
765*38e8c45fSAndroid Build Coastguard Worker 
766*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::write(
767*38e8c45fSAndroid Build Coastguard Worker             buffer, size, static_cast<uint32_t>(mDeltas.size()));
768*38e8c45fSAndroid Build Coastguard Worker     for (auto& d : mDeltas) {
769*38e8c45fSAndroid Build Coastguard Worker         status_t status = d.flatten(buffer, size, fds, count);
770*38e8c45fSAndroid Build Coastguard Worker         if (status != NO_ERROR) {
771*38e8c45fSAndroid Build Coastguard Worker             return status;
772*38e8c45fSAndroid Build Coastguard Worker         }
773*38e8c45fSAndroid Build Coastguard Worker     }
774*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
775*38e8c45fSAndroid Build Coastguard Worker }
776*38e8c45fSAndroid Build Coastguard Worker 
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)777*38e8c45fSAndroid Build Coastguard Worker status_t FrameEventHistoryDelta::unflatten(
778*38e8c45fSAndroid Build Coastguard Worker             void const*& buffer, size_t& size, int const*& fds, size_t& count) {
779*38e8c45fSAndroid Build Coastguard Worker     if (size < minFlattenedSize()) {
780*38e8c45fSAndroid Build Coastguard Worker         return NO_MEMORY;
781*38e8c45fSAndroid Build Coastguard Worker     }
782*38e8c45fSAndroid Build Coastguard Worker 
783*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, mCompositorTiming);
784*38e8c45fSAndroid Build Coastguard Worker 
785*38e8c45fSAndroid Build Coastguard Worker     uint32_t deltaCount = 0;
786*38e8c45fSAndroid Build Coastguard Worker     FlattenableUtils::read(buffer, size, deltaCount);
787*38e8c45fSAndroid Build Coastguard Worker     if (deltaCount > UINT8_MAX) {
788*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
789*38e8c45fSAndroid Build Coastguard Worker     }
790*38e8c45fSAndroid Build Coastguard Worker     mDeltas.resize(deltaCount);
791*38e8c45fSAndroid Build Coastguard Worker     for (auto& d : mDeltas) {
792*38e8c45fSAndroid Build Coastguard Worker         status_t status = d.unflatten(buffer, size, fds, count);
793*38e8c45fSAndroid Build Coastguard Worker         if (status != NO_ERROR) {
794*38e8c45fSAndroid Build Coastguard Worker             return status;
795*38e8c45fSAndroid Build Coastguard Worker         }
796*38e8c45fSAndroid Build Coastguard Worker     }
797*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
798*38e8c45fSAndroid Build Coastguard Worker }
799*38e8c45fSAndroid Build Coastguard Worker 
begin() const800*38e8c45fSAndroid Build Coastguard Worker std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::begin() const {
801*38e8c45fSAndroid Build Coastguard Worker     return mDeltas.begin();
802*38e8c45fSAndroid Build Coastguard Worker }
803*38e8c45fSAndroid Build Coastguard Worker 
end() const804*38e8c45fSAndroid Build Coastguard Worker std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::end() const {
805*38e8c45fSAndroid Build Coastguard Worker     return mDeltas.end();
806*38e8c45fSAndroid Build Coastguard Worker }
807*38e8c45fSAndroid Build Coastguard Worker 
808*38e8c45fSAndroid Build Coastguard Worker } // namespace android
809