blob: 73537bfc275dd170f10c71802572a490ae82de9d [file] [log] [blame]
Brian Andersond6927fb2016-07-23 23:37:30 -07001/*
2* Copyright 2016 The Android Open Source Project
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16
17#include <gui/FrameTimestamps.h>
18
Brian Anderson3d4039d2016-09-23 16:31:30 -070019#include <cutils/compiler.h> // For CC_[UN]LIKELY
Brian Andersond6927fb2016-07-23 23:37:30 -070020#include <inttypes.h>
Brian Anderson175a7202016-10-10 16:52:56 -070021#include <utils/Log.h>
Brian Andersond6927fb2016-07-23 23:37:30 -070022#include <utils/String8.h>
23
24#include <algorithm>
25#include <limits>
Brian Anderson3890c392016-07-25 12:48:08 -070026#include <numeric>
Brian Andersond6927fb2016-07-23 23:37:30 -070027
28namespace android {
29
Brian Andersond6927fb2016-07-23 23:37:30 -070030
31// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -070032// FrameEvents
33// ============================================================================
34
Brian Anderson3890c392016-07-25 12:48:08 -070035bool FrameEvents::hasPostedInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070036 return Fence::isValidTimestamp(postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -070037}
38
39bool FrameEvents::hasRequestedPresentInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070040 return Fence::isValidTimestamp(requestedPresentTime);
Brian Anderson3890c392016-07-25 12:48:08 -070041}
42
43bool FrameEvents::hasLatchInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070044 return Fence::isValidTimestamp(latchTime);
Brian Anderson3890c392016-07-25 12:48:08 -070045}
46
47bool FrameEvents::hasFirstRefreshStartInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070048 return Fence::isValidTimestamp(firstRefreshStartTime);
Brian Anderson3890c392016-07-25 12:48:08 -070049}
50
51bool FrameEvents::hasLastRefreshStartInfo() const {
52 // The last refresh start time may continue to update until a new frame
53 // is latched. We know we have the final value once the release or retire
54 // info is set. See ConsumerFrameEventHistory::addRetire/Release.
55 return addRetireCalled || addReleaseCalled;
56}
57
Brian Andersonf6386862016-10-31 16:34:13 -070058bool FrameEvents::hasDequeueReadyInfo() const {
59 return Fence::isValidTimestamp(dequeueReadyTime);
60}
61
Brian Anderson3890c392016-07-25 12:48:08 -070062bool FrameEvents::hasAcquireInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070063 return acquireFence->isValid();
Brian Anderson3890c392016-07-25 12:48:08 -070064}
65
66bool FrameEvents::hasGpuCompositionDoneInfo() const {
67 // We may not get a gpuCompositionDone in addPostComposite if
68 // client/gles compositing isn't needed.
69 return addPostCompositeCalled;
70}
71
72bool FrameEvents::hasDisplayPresentInfo() const {
73 // We may not get a displayPresent in addPostComposite for HWC1.
74 return addPostCompositeCalled;
75}
76
77bool FrameEvents::hasDisplayRetireInfo() const {
78 // We may not get a displayRetire in addRetire for HWC2.
79 return addRetireCalled;
80}
81
82bool FrameEvents::hasReleaseInfo() const {
83 return addReleaseCalled;
84}
85
Brian Anderson3d4039d2016-09-23 16:31:30 -070086void FrameEvents::checkFencesForCompletion() {
87 acquireFence->getSignalTime();
88 gpuCompositionDoneFence->getSignalTime();
89 displayPresentFence->getSignalTime();
90 displayRetireFence->getSignalTime();
91 releaseFence->getSignalTime();
Brian Andersond6927fb2016-07-23 23:37:30 -070092}
93
Brian Anderson3d4039d2016-09-23 16:31:30 -070094static void dumpFenceTime(String8& outString, const char* name,
95 bool pending, const FenceTime& fenceTime) {
96 outString.appendFormat("--- %s", name);
97 nsecs_t signalTime = fenceTime.getCachedSignalTime();
98 if (Fence::isValidTimestamp(signalTime)) {
99 outString.appendFormat("%" PRId64 "\n", signalTime);
100 } else if (pending || signalTime == Fence::SIGNAL_TIME_PENDING) {
101 outString.appendFormat("Pending\n");
102 } else if (&fenceTime == FenceTime::NO_FENCE.get()){
103 outString.appendFormat("N/A\n");
104 } else {
105 outString.appendFormat("Error\n");
106 }
Brian Andersond6927fb2016-07-23 23:37:30 -0700107}
108
109void FrameEvents::dump(String8& outString) const
110{
111 if (!valid) {
112 return;
113 }
114
115 outString.appendFormat("-- Frame %" PRIu64 "\n", frameNumber);
116 outString.appendFormat("--- Posted \t%" PRId64 "\n", postedTime);
117 outString.appendFormat("--- Req. Present\t%" PRId64 "\n", requestedPresentTime);
118
119 outString.appendFormat("--- Latched \t");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700120 if (Fence::isValidTimestamp(latchTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700121 outString.appendFormat("%" PRId64 "\n", latchTime);
122 } else {
123 outString.appendFormat("Pending\n");
124 }
125
126 outString.appendFormat("--- Refresh (First)\t");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700127 if (Fence::isValidTimestamp(firstRefreshStartTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700128 outString.appendFormat("%" PRId64 "\n", firstRefreshStartTime);
129 } else {
130 outString.appendFormat("Pending\n");
131 }
132
133 outString.appendFormat("--- Refresh (Last)\t");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700134 if (Fence::isValidTimestamp(lastRefreshStartTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700135 outString.appendFormat("%" PRId64 "\n", lastRefreshStartTime);
136 } else {
137 outString.appendFormat("Pending\n");
138 }
139
Brian Anderson3d4039d2016-09-23 16:31:30 -0700140 dumpFenceTime(outString, "Acquire \t",
141 true, *acquireFence);
142 dumpFenceTime(outString, "GPU Composite Done\t",
143 !addPostCompositeCalled, *gpuCompositionDoneFence);
144 dumpFenceTime(outString, "Display Present \t",
145 !addPostCompositeCalled, *displayPresentFence);
146 dumpFenceTime(outString, "Display Retire \t",
147 !addRetireCalled, *displayRetireFence);
Brian Andersonf6386862016-10-31 16:34:13 -0700148
149 outString.appendFormat("--- DequeueReady \t");
150 if (Fence::isValidTimestamp(dequeueReadyTime)) {
151 outString.appendFormat("%" PRId64 "\n", dequeueReadyTime);
152 } else {
153 outString.appendFormat("Pending\n");
154 }
155
Brian Anderson3d4039d2016-09-23 16:31:30 -0700156 dumpFenceTime(outString, "Release \t",
157 true, *releaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700158}
159
160
161// ============================================================================
162// FrameEventHistory
163// ============================================================================
164
165namespace {
166
167struct FrameNumberEqual {
168 FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
169 bool operator()(const FrameEvents& frame) {
170 return frame.valid && mFrameNumber == frame.frameNumber;
171 }
172 const uint64_t mFrameNumber;
173};
174
175} // namespace
176
Brian Anderson3890c392016-07-25 12:48:08 -0700177FrameEventHistory::~FrameEventHistory() = default;
Brian Andersond6927fb2016-07-23 23:37:30 -0700178
179FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber) {
180 auto frame = std::find_if(
181 mFrames.begin(), mFrames.end(), FrameNumberEqual(frameNumber));
182 return frame == mFrames.end() ? nullptr : &(*frame);
183}
184
185FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber, size_t* iHint) {
186 *iHint = std::min(*iHint, mFrames.size());
187 auto hint = mFrames.begin() + *iHint;
188 auto frame = std::find_if(
189 hint, mFrames.end(), FrameNumberEqual(frameNumber));
190 if (frame == mFrames.end()) {
191 frame = std::find_if(
192 mFrames.begin(), hint, FrameNumberEqual(frameNumber));
193 if (frame == hint) {
194 return nullptr;
195 }
196 }
197 *iHint = static_cast<size_t>(std::distance(mFrames.begin(), frame));
198 return &(*frame);
199}
200
201void FrameEventHistory::checkFencesForCompletion() {
202 for (auto& frame : mFrames) {
203 frame.checkFencesForCompletion();
204 }
205}
206
207// Uses !|valid| as the MSB.
208static bool FrameNumberLessThan(
209 const FrameEvents& lhs, const FrameEvents& rhs) {
210 if (lhs.valid == rhs.valid) {
211 return lhs.frameNumber < rhs.frameNumber;
212 }
213 return lhs.valid;
214}
215
216void FrameEventHistory::dump(String8& outString) const {
217 auto earliestFrame = std::min_element(
218 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
219 if (!earliestFrame->valid) {
220 outString.appendFormat("-- N/A\n");
221 return;
222 }
223 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
224 frame->dump(outString);
225 }
226 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
227 frame->dump(outString);
228 }
229}
230
Brian Andersond6927fb2016-07-23 23:37:30 -0700231
Brian Anderson3890c392016-07-25 12:48:08 -0700232// ============================================================================
233// ProducerFrameEventHistory
234// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -0700235
Brian Anderson3890c392016-07-25 12:48:08 -0700236ProducerFrameEventHistory::~ProducerFrameEventHistory() = default;
237
238void ProducerFrameEventHistory::updateAcquireFence(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700239 uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) {
Brian Anderson3890c392016-07-25 12:48:08 -0700240 FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
Brian Andersond6927fb2016-07-23 23:37:30 -0700241 if (frame == nullptr) {
Brian Anderson3890c392016-07-25 12:48:08 -0700242 ALOGE("ProducerFrameEventHistory::updateAcquireFence: "
243 "Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700244 return;
245 }
246
Brian Anderson3890c392016-07-25 12:48:08 -0700247 if (acquire->isValid()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700248 mAcquireTimeline.push(acquire);
249 frame->acquireFence = std::move(acquire);
Brian Anderson3890c392016-07-25 12:48:08 -0700250 } else {
251 // If there isn't an acquire fence, assume that buffer was
252 // ready for the consumer when posted.
Brian Anderson3d4039d2016-09-23 16:31:30 -0700253 frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700254 }
255}
256
Brian Anderson3890c392016-07-25 12:48:08 -0700257void ProducerFrameEventHistory::applyDelta(
258 const FrameEventHistoryDelta& delta) {
259 for (auto& d : delta.mDeltas) {
260 // Avoid out-of-bounds access.
261 if (d.mIndex >= mFrames.size()) {
262 ALOGE("ProducerFrameEventHistory::applyDelta: Bad index.");
263 return;
264 }
265
266 FrameEvents& frame = mFrames[d.mIndex];
267
268 frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
269 frame.addRetireCalled = d.mAddRetireCalled != 0;
270 frame.addReleaseCalled = d.mAddReleaseCalled != 0;
271
272 frame.postedTime = d.mPostedTime;
273 frame.requestedPresentTime = d.mRequestedPresentTime;
274 frame.latchTime = d.mLatchTime;
275 frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
276 frame.lastRefreshStartTime = d.mLastRefreshStartTime;
Brian Andersonf6386862016-10-31 16:34:13 -0700277 frame.dequeueReadyTime = d.mDequeueReadyTime;
Brian Anderson3890c392016-07-25 12:48:08 -0700278
Brian Anderson3d4039d2016-09-23 16:31:30 -0700279 if (frame.frameNumber != d.mFrameNumber) {
280 // We got a new frame. Initialize some of the fields.
Brian Anderson3890c392016-07-25 12:48:08 -0700281 frame.frameNumber = d.mFrameNumber;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700282 frame.acquireFence = FenceTime::NO_FENCE;
283 frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
284 frame.displayPresentFence = FenceTime::NO_FENCE;
285 frame.displayRetireFence = FenceTime::NO_FENCE;
286 frame.releaseFence = FenceTime::NO_FENCE;
Brian Anderson3890c392016-07-25 12:48:08 -0700287 // The consumer only sends valid frames.
288 frame.valid = true;
Brian Andersond6927fb2016-07-23 23:37:30 -0700289 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700290
291 applyFenceDelta(&mGpuCompositionDoneTimeline,
292 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
293 applyFenceDelta(&mPresentTimeline,
294 &frame.displayPresentFence, d.mDisplayPresentFence);
295 applyFenceDelta(&mRetireTimeline,
296 &frame.displayRetireFence, d.mDisplayRetireFence);
297 applyFenceDelta(&mReleaseTimeline,
298 &frame.releaseFence, d.mReleaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700299 }
300}
301
Brian Anderson3d4039d2016-09-23 16:31:30 -0700302void ProducerFrameEventHistory::updateSignalTimes() {
303 mAcquireTimeline.updateSignalTimes();
304 mGpuCompositionDoneTimeline.updateSignalTimes();
305 mPresentTimeline.updateSignalTimes();
306 mRetireTimeline.updateSignalTimes();
307 mReleaseTimeline.updateSignalTimes();
308}
309
Brian Anderson3da8d272016-07-28 16:20:47 -0700310void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
311 std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
312 if (CC_UNLIKELY(dst == nullptr)) {
313 ALOGE("applyFenceDelta: dst is null.");
314 return;
315 }
316
317 switch (src.state) {
318 case FenceTime::Snapshot::State::EMPTY:
319 return;
320 case FenceTime::Snapshot::State::FENCE:
321 if (CC_UNLIKELY((*dst)->isValid())) {
322 ALOGE("applyFenceDelta: Unexpected fence.");
323 }
324 *dst = createFenceTime(src.fence);
325 timeline->push(*dst);
326 return;
327 case FenceTime::Snapshot::State::SIGNAL_TIME:
328 if ((*dst)->isValid()) {
329 (*dst)->applyTrustedSnapshot(src);
330 } else {
331 *dst = std::make_shared<FenceTime>(src.signalTime);
332 }
333 return;
334 }
335}
336
337std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
338 const sp<Fence>& fence) const {
339 return std::make_shared<FenceTime>(fence);
340}
341
Brian Anderson3890c392016-07-25 12:48:08 -0700342
343// ============================================================================
344// ConsumerFrameEventHistory
345// ============================================================================
346
347ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
348
349void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
350 // Overwrite all fields of the frame with default values unless set here.
351 FrameEvents newTimestamps;
352 newTimestamps.frameNumber = newEntry.frameNumber;
353 newTimestamps.postedTime = newEntry.postedTime;
354 newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
355 newTimestamps.acquireFence = newEntry.acquireFence;
356 newTimestamps.valid = true;
357 mFrames[mQueueOffset] = newTimestamps;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700358
359 // Note: We avoid sending the acquire fence back to the caller since
360 // they have the original one already, so there is no need to set the
361 // acquire dirty bit.
Brian Anderson3890c392016-07-25 12:48:08 -0700362 mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
Brian Anderson3890c392016-07-25 12:48:08 -0700363
364 mQueueOffset = (mQueueOffset + 1) % mFrames.size();
365}
366
367void ConsumerFrameEventHistory::addLatch(
368 uint64_t frameNumber, nsecs_t latchTime) {
369 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
370 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800371 ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700372 return;
373 }
374 frame->latchTime = latchTime;
375 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
376}
377
378void ConsumerFrameEventHistory::addPreComposition(
379 uint64_t frameNumber, nsecs_t refreshStartTime) {
380 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
381 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800382 ALOGE_IF(mProducerWantsEvents,
383 "addPreComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700384 return;
385 }
386 frame->lastRefreshStartTime = refreshStartTime;
387 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
Brian Anderson3d4039d2016-09-23 16:31:30 -0700388 if (!Fence::isValidTimestamp(frame->firstRefreshStartTime)) {
Brian Anderson3890c392016-07-25 12:48:08 -0700389 frame->firstRefreshStartTime = refreshStartTime;
390 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
391 }
392}
393
394void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
Brian Anderson3d4039d2016-09-23 16:31:30 -0700395 const std::shared_ptr<FenceTime>& gpuCompositionDone,
396 const std::shared_ptr<FenceTime>& displayPresent) {
Brian Anderson3890c392016-07-25 12:48:08 -0700397 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
398 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800399 ALOGE_IF(mProducerWantsEvents,
400 "addPostComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700401 return;
402 }
403 // Only get GPU and present info for the first composite.
404 if (!frame->addPostCompositeCalled) {
405 frame->addPostCompositeCalled = true;
406 frame->gpuCompositionDoneFence = gpuCompositionDone;
407 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GL_COMPOSITION_DONE>();
408 if (!frame->displayPresentFence->isValid()) {
409 frame->displayPresentFence = displayPresent;
410 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
411 }
412 }
413}
414
415void ConsumerFrameEventHistory::addRetire(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700416 uint64_t frameNumber, const std::shared_ptr<FenceTime>& displayRetire) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700417 FrameEvents* frame = getFrame(frameNumber, &mRetireOffset);
418 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800419 ALOGE_IF(mProducerWantsEvents, "addRetire: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700420 return;
421 }
422 frame->addRetireCalled = true;
423 frame->displayRetireFence = displayRetire;
Brian Anderson3890c392016-07-25 12:48:08 -0700424 mFramesDirty[mRetireOffset].setDirty<FrameEvent::DISPLAY_RETIRE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700425}
426
Brian Andersonf6386862016-10-31 16:34:13 -0700427void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber,
428 nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700429 FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
430 if (frame == nullptr) {
Brian Anderson3890c392016-07-25 12:48:08 -0700431 ALOGE("ConsumerFrameEventHistory::addRelease: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700432 return;
433 }
Brian Anderson3890c392016-07-25 12:48:08 -0700434 frame->addReleaseCalled = true;
Brian Andersonf6386862016-10-31 16:34:13 -0700435 frame->dequeueReadyTime = dequeueReadyTime;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700436 frame->releaseFence = std::move(release);
Brian Anderson3890c392016-07-25 12:48:08 -0700437 mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700438}
439
Brian Anderson3d4039d2016-09-23 16:31:30 -0700440void ConsumerFrameEventHistory::getFrameDelta(
441 FrameEventHistoryDelta* delta,
442 const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800443 mProducerWantsEvents = true;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700444 size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
445 if (mFramesDirty[i].anyDirty()) {
446 delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
447 mFramesDirty[i].reset();
448 }
449}
450
Brian Anderson3890c392016-07-25 12:48:08 -0700451void ConsumerFrameEventHistory::getAndResetDelta(
452 FrameEventHistoryDelta* delta) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700453 // Write these in order of frame number so that it is easy to
454 // add them to a FenceTimeline in the proper order producer side.
Brian Anderson3890c392016-07-25 12:48:08 -0700455 delta->mDeltas.reserve(mFramesDirty.size());
Brian Anderson3d4039d2016-09-23 16:31:30 -0700456 auto earliestFrame = std::min_element(
457 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
458 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
459 getFrameDelta(delta, frame);
460 }
461 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
462 getFrameDelta(delta, frame);
Brian Anderson3890c392016-07-25 12:48:08 -0700463 }
464}
465
466
467// ============================================================================
468// FrameEventsDelta
469// ============================================================================
470
471FrameEventsDelta::FrameEventsDelta(
472 size_t index,
473 const FrameEvents& frameTimestamps,
474 const FrameEventDirtyFields& dirtyFields)
475 : mIndex(index),
476 mFrameNumber(frameTimestamps.frameNumber),
477 mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
478 mAddRetireCalled(frameTimestamps.addRetireCalled),
479 mAddReleaseCalled(frameTimestamps.addReleaseCalled),
480 mPostedTime(frameTimestamps.postedTime),
481 mRequestedPresentTime(frameTimestamps.requestedPresentTime),
482 mLatchTime(frameTimestamps.latchTime),
483 mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
Brian Andersonf6386862016-10-31 16:34:13 -0700484 mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime),
485 mDequeueReadyTime(frameTimestamps.dequeueReadyTime) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700486 if (dirtyFields.isDirty<FrameEvent::GL_COMPOSITION_DONE>()) {
487 mGpuCompositionDoneFence =
488 frameTimestamps.gpuCompositionDoneFence->getSnapshot();
489 }
490 if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
491 mDisplayPresentFence =
492 frameTimestamps.displayPresentFence->getSnapshot();
493 }
494 if (dirtyFields.isDirty<FrameEvent::DISPLAY_RETIRE>()) {
495 mDisplayRetireFence = frameTimestamps.displayRetireFence->getSnapshot();
496 }
497 if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
498 mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
499 }
Brian Anderson3890c392016-07-25 12:48:08 -0700500}
501
502size_t FrameEventsDelta::minFlattenedSize() {
503 constexpr size_t min =
504 sizeof(FrameEventsDelta::mFrameNumber) +
505 sizeof(uint8_t) + // mIndex
506 sizeof(uint8_t) + // mAddPostCompositeCalled
507 sizeof(uint8_t) + // mAddRetireCalled
508 sizeof(uint8_t) + // mAddReleaseCalled
509 sizeof(FrameEventsDelta::mPostedTime) +
510 sizeof(FrameEventsDelta::mRequestedPresentTime) +
511 sizeof(FrameEventsDelta::mLatchTime) +
512 sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
Brian Andersonf6386862016-10-31 16:34:13 -0700513 sizeof(FrameEventsDelta::mLastRefreshStartTime) +
514 sizeof(FrameEventsDelta::mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700515 return min;
516}
517
518// Flattenable implementation
519size_t FrameEventsDelta::getFlattenedSize() const {
520 auto fences = allFences(this);
521 return minFlattenedSize() +
522 std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700523 [](size_t a, const FenceTime::Snapshot* fence) {
524 return a + fence->getFlattenedSize();
Brian Anderson3890c392016-07-25 12:48:08 -0700525 });
526}
527
528size_t FrameEventsDelta::getFdCount() const {
529 auto fences = allFences(this);
530 return std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700531 [](size_t a, const FenceTime::Snapshot* fence) {
532 return a + fence->getFdCount();
Brian Anderson3890c392016-07-25 12:48:08 -0700533 });
534}
535
536status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
537 size_t& count) const {
538 if (size < getFlattenedSize() || count < getFdCount()) {
539 return NO_MEMORY;
540 }
541
542 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY ||
543 mIndex > std::numeric_limits<uint8_t>::max()) {
544 return BAD_VALUE;
545 }
546
547 FlattenableUtils::write(buffer, size, mFrameNumber);
548
549 // These are static_cast to uint8_t for alignment.
550 FlattenableUtils::write(buffer, size, static_cast<uint8_t>(mIndex));
551 FlattenableUtils::write(
552 buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
553 FlattenableUtils::write(
554 buffer, size, static_cast<uint8_t>(mAddRetireCalled));
555 FlattenableUtils::write(
556 buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
557
558 FlattenableUtils::write(buffer, size, mPostedTime);
559 FlattenableUtils::write(buffer, size, mRequestedPresentTime);
560 FlattenableUtils::write(buffer, size, mLatchTime);
561 FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
562 FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700563 FlattenableUtils::write(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700564
565 // Fences
566 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700567 status_t status = fence->flatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700568 if (status != NO_ERROR) {
569 return status;
570 }
571 }
572 return NO_ERROR;
573}
574
575status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
576 int const*& fds, size_t& count) {
577 if (size < minFlattenedSize()) {
578 return NO_MEMORY;
579 }
580
581 FlattenableUtils::read(buffer, size, mFrameNumber);
582
583 // These were written as uint8_t for alignment.
584 uint8_t temp = 0;
585 FlattenableUtils::read(buffer, size, temp);
586 mIndex = temp;
587 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY) {
588 return BAD_VALUE;
589 }
590 FlattenableUtils::read(buffer, size, temp);
591 mAddPostCompositeCalled = static_cast<bool>(temp);
592 FlattenableUtils::read(buffer, size, temp);
593 mAddRetireCalled = static_cast<bool>(temp);
594 FlattenableUtils::read(buffer, size, temp);
595 mAddReleaseCalled = static_cast<bool>(temp);
596
597 FlattenableUtils::read(buffer, size, mPostedTime);
598 FlattenableUtils::read(buffer, size, mRequestedPresentTime);
599 FlattenableUtils::read(buffer, size, mLatchTime);
600 FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
601 FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700602 FlattenableUtils::read(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700603
604 // Fences
605 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700606 status_t status = fence->unflatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700607 if (status != NO_ERROR) {
608 return status;
609 }
610 }
611 return NO_ERROR;
612}
613
614
615// ============================================================================
616// FrameEventHistoryDelta
617// ============================================================================
618
Brian Anderson3d4039d2016-09-23 16:31:30 -0700619FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
620 FrameEventHistoryDelta&& src) {
621 if (CC_UNLIKELY(!mDeltas.empty())) {
622 ALOGE("FrameEventHistoryDelta: Clobbering history.");
623 }
624 mDeltas = std::move(src.mDeltas);
625 ALOGE_IF(src.mDeltas.empty(), "Source mDeltas not empty.");
626 return *this;
627}
628
Brian Anderson3890c392016-07-25 12:48:08 -0700629size_t FrameEventHistoryDelta::minFlattenedSize() {
630 return sizeof(uint32_t);
631}
632
633size_t FrameEventHistoryDelta::getFlattenedSize() const {
634 return minFlattenedSize() +
635 std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
636 [](size_t a, const FrameEventsDelta& delta) {
637 return a + delta.getFlattenedSize();
638 });
639}
640
641size_t FrameEventHistoryDelta::getFdCount() const {
642 return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
643 [](size_t a, const FrameEventsDelta& delta) {
644 return a + delta.getFdCount();
645 });
646}
647
648status_t FrameEventHistoryDelta::flatten(
649 void*& buffer, size_t& size, int*& fds, size_t& count) const {
650 if (mDeltas.size() > FrameEventHistory::MAX_FRAME_HISTORY) {
651 return BAD_VALUE;
652 }
653 if (size < getFlattenedSize()) {
654 return NO_MEMORY;
655 }
656
657 FlattenableUtils::write(
658 buffer, size, static_cast<uint32_t>(mDeltas.size()));
659 for (auto& d : mDeltas) {
660 status_t status = d.flatten(buffer, size, fds, count);
661 if (status != NO_ERROR) {
662 return status;
663 }
664 }
665 return NO_ERROR;
666}
667
668status_t FrameEventHistoryDelta::unflatten(
669 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
670 if (size < minFlattenedSize()) {
671 return NO_MEMORY;
672 }
673
674 uint32_t deltaCount = 0;
675 FlattenableUtils::read(buffer, size, deltaCount);
676 if (deltaCount > FrameEventHistory::MAX_FRAME_HISTORY) {
677 return BAD_VALUE;
678 }
679 mDeltas.resize(deltaCount);
680 for (auto& d : mDeltas) {
681 status_t status = d.unflatten(buffer, size, fds, count);
682 if (status != NO_ERROR) {
683 return status;
684 }
685 }
686 return NO_ERROR;
687}
688
689
Brian Andersond6927fb2016-07-23 23:37:30 -0700690} // namespace android