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