blob: 4b98cff61543ecef443cbfc0116b235f5f91b261 [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
19#include <inttypes.h>
20#include <utils/String8.h>
21
22#include <algorithm>
23#include <limits>
Brian Anderson3890c392016-07-25 12:48:08 -070024#include <numeric>
Brian Andersond6927fb2016-07-23 23:37:30 -070025
26namespace android {
27
28static inline bool isValidTimestamp(nsecs_t time) {
29 return time > 0 && time < INT64_MAX;
30}
31
32// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -070033// FrameEvents
34// ============================================================================
35
Brian Anderson3890c392016-07-25 12:48:08 -070036bool FrameEvents::hasPostedInfo() const {
37 return isValidTimestamp(postedTime);
38}
39
40bool FrameEvents::hasRequestedPresentInfo() const {
41 return isValidTimestamp(requestedPresentTime);
42}
43
44bool FrameEvents::hasLatchInfo() const {
45 return isValidTimestamp(latchTime);
46}
47
48bool FrameEvents::hasFirstRefreshStartInfo() const {
49 return isValidTimestamp(firstRefreshStartTime);
50}
51
52bool FrameEvents::hasLastRefreshStartInfo() const {
53 // The last refresh start time may continue to update until a new frame
54 // is latched. We know we have the final value once the release or retire
55 // info is set. See ConsumerFrameEventHistory::addRetire/Release.
56 return addRetireCalled || addReleaseCalled;
57}
58
59bool FrameEvents::hasAcquireInfo() const {
60 return isValidTimestamp(acquireTime) || acquireFence->isValid();
61}
62
63bool FrameEvents::hasGpuCompositionDoneInfo() const {
64 // We may not get a gpuCompositionDone in addPostComposite if
65 // client/gles compositing isn't needed.
66 return addPostCompositeCalled;
67}
68
69bool FrameEvents::hasDisplayPresentInfo() const {
70 // We may not get a displayPresent in addPostComposite for HWC1.
71 return addPostCompositeCalled;
72}
73
74bool FrameEvents::hasDisplayRetireInfo() const {
75 // We may not get a displayRetire in addRetire for HWC2.
76 return addRetireCalled;
77}
78
79bool FrameEvents::hasReleaseInfo() const {
80 return addReleaseCalled;
81}
82
Brian Andersond6927fb2016-07-23 23:37:30 -070083static void checkFenceForCompletion(sp<Fence>* fence, nsecs_t* dstTime) {
84 if ((*fence)->isValid()) {
85 nsecs_t time = (*fence)->getSignalTime();
86 if (isValidTimestamp(time)) {
87 *dstTime = time;
88 *fence = Fence::NO_FENCE;
89 }
90 }
91}
92
93void FrameEvents::checkFencesForCompletion() {
94 checkFenceForCompletion(&acquireFence, &acquireTime);
95 checkFenceForCompletion(&gpuCompositionDoneFence, &gpuCompositionDoneTime);
96 checkFenceForCompletion(&displayPresentFence, &displayPresentTime);
97 checkFenceForCompletion(&displayRetireFence, &displayRetireTime);
98 checkFenceForCompletion(&releaseFence, &releaseTime);
99}
100
101void FrameEvents::dump(String8& outString) const
102{
103 if (!valid) {
104 return;
105 }
106
107 outString.appendFormat("-- Frame %" PRIu64 "\n", frameNumber);
108 outString.appendFormat("--- Posted \t%" PRId64 "\n", postedTime);
109 outString.appendFormat("--- Req. Present\t%" PRId64 "\n", requestedPresentTime);
110
111 outString.appendFormat("--- Latched \t");
112 if (isValidTimestamp(latchTime)) {
113 outString.appendFormat("%" PRId64 "\n", latchTime);
114 } else {
115 outString.appendFormat("Pending\n");
116 }
117
118 outString.appendFormat("--- Refresh (First)\t");
119 if (isValidTimestamp(firstRefreshStartTime)) {
120 outString.appendFormat("%" PRId64 "\n", firstRefreshStartTime);
121 } else {
122 outString.appendFormat("Pending\n");
123 }
124
125 outString.appendFormat("--- Refresh (Last)\t");
126 if (isValidTimestamp(lastRefreshStartTime)) {
127 outString.appendFormat("%" PRId64 "\n", lastRefreshStartTime);
128 } else {
129 outString.appendFormat("Pending\n");
130 }
131
132 outString.appendFormat("--- Acquire \t");
133 if (isValidTimestamp(acquireTime)) {
134 outString.appendFormat("%" PRId64 "\n", acquireTime);
135 } else {
136 outString.appendFormat("Pending\n");
137 }
138
139 outString.appendFormat("--- GPU Composite Done\t");
140 if (isValidTimestamp(gpuCompositionDoneTime)) {
141 outString.appendFormat("%" PRId64 "\n", gpuCompositionDoneTime);
142 } else if (!addPostCompositeCalled || gpuCompositionDoneFence->isValid()) {
143 outString.appendFormat("Pending\n");
144 } else {
145 outString.appendFormat("N/A\n");
146 }
147
148 outString.appendFormat("--- Display Present\t");
149 if (isValidTimestamp(displayPresentTime)) {
150 outString.appendFormat("%" PRId64 "\n", displayPresentTime);
151 } else if (!addPostCompositeCalled || displayPresentFence->isValid()) {
152 outString.appendFormat("Pending\n");
153 } else {
154 outString.appendFormat("N/A\n");
155 }
156
157 outString.appendFormat("--- Display Retire\t");
158 if (isValidTimestamp(displayRetireTime)) {
159 outString.appendFormat("%" PRId64 "\n", displayRetireTime);
160 } else if (!addRetireCalled || displayRetireFence->isValid()) {
161 outString.appendFormat("Pending\n");
162 } else {
163 outString.appendFormat("N/A\n");
164 }
165
166 outString.appendFormat("--- Release \t");
167 if (isValidTimestamp(releaseTime)) {
168 outString.appendFormat("%" PRId64 "\n", releaseTime);
169 } else {
170 outString.appendFormat("Pending\n");
171 }
172}
173
174
175// ============================================================================
176// FrameEventHistory
177// ============================================================================
178
179namespace {
180
181struct FrameNumberEqual {
182 FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
183 bool operator()(const FrameEvents& frame) {
184 return frame.valid && mFrameNumber == frame.frameNumber;
185 }
186 const uint64_t mFrameNumber;
187};
188
189} // namespace
190
Brian Anderson3890c392016-07-25 12:48:08 -0700191FrameEventHistory::~FrameEventHistory() = default;
Brian Andersond6927fb2016-07-23 23:37:30 -0700192
193FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber) {
194 auto frame = std::find_if(
195 mFrames.begin(), mFrames.end(), FrameNumberEqual(frameNumber));
196 return frame == mFrames.end() ? nullptr : &(*frame);
197}
198
199FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber, size_t* iHint) {
200 *iHint = std::min(*iHint, mFrames.size());
201 auto hint = mFrames.begin() + *iHint;
202 auto frame = std::find_if(
203 hint, mFrames.end(), FrameNumberEqual(frameNumber));
204 if (frame == mFrames.end()) {
205 frame = std::find_if(
206 mFrames.begin(), hint, FrameNumberEqual(frameNumber));
207 if (frame == hint) {
208 return nullptr;
209 }
210 }
211 *iHint = static_cast<size_t>(std::distance(mFrames.begin(), frame));
212 return &(*frame);
213}
214
215void FrameEventHistory::checkFencesForCompletion() {
216 for (auto& frame : mFrames) {
217 frame.checkFencesForCompletion();
218 }
219}
220
221// Uses !|valid| as the MSB.
222static bool FrameNumberLessThan(
223 const FrameEvents& lhs, const FrameEvents& rhs) {
224 if (lhs.valid == rhs.valid) {
225 return lhs.frameNumber < rhs.frameNumber;
226 }
227 return lhs.valid;
228}
229
230void FrameEventHistory::dump(String8& outString) const {
231 auto earliestFrame = std::min_element(
232 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
233 if (!earliestFrame->valid) {
234 outString.appendFormat("-- N/A\n");
235 return;
236 }
237 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
238 frame->dump(outString);
239 }
240 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
241 frame->dump(outString);
242 }
243}
244
Brian Andersond6927fb2016-07-23 23:37:30 -0700245
Brian Anderson3890c392016-07-25 12:48:08 -0700246// ============================================================================
247// ProducerFrameEventHistory
248// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -0700249
Brian Anderson3890c392016-07-25 12:48:08 -0700250ProducerFrameEventHistory::~ProducerFrameEventHistory() = default;
251
252void ProducerFrameEventHistory::updateAcquireFence(
253 uint64_t frameNumber, sp<Fence> acquire) {
254 FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
Brian Andersond6927fb2016-07-23 23:37:30 -0700255 if (frame == nullptr) {
Brian Anderson3890c392016-07-25 12:48:08 -0700256 ALOGE("ProducerFrameEventHistory::updateAcquireFence: "
257 "Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700258 return;
259 }
260
Brian Anderson3890c392016-07-25 12:48:08 -0700261 if (acquire->isValid()) {
262 frame->acquireFence = acquire;
263 } else {
264 // If there isn't an acquire fence, assume that buffer was
265 // ready for the consumer when posted.
266 frame->acquireTime = frame->postedTime;
267 }
268}
269
270static void applyFenceDelta(sp<Fence>* dst, const sp<Fence>& src) {
271 if (src->isValid()) {
272 if ((*dst)->isValid()) {
273 ALOGE("applyFenceDelta: Unexpected fence.");
274 }
275 *dst = src;
276 }
277}
278
279void ProducerFrameEventHistory::applyDelta(
280 const FrameEventHistoryDelta& delta) {
281 for (auto& d : delta.mDeltas) {
282 // Avoid out-of-bounds access.
283 if (d.mIndex >= mFrames.size()) {
284 ALOGE("ProducerFrameEventHistory::applyDelta: Bad index.");
285 return;
286 }
287
288 FrameEvents& frame = mFrames[d.mIndex];
289
290 frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
291 frame.addRetireCalled = d.mAddRetireCalled != 0;
292 frame.addReleaseCalled = d.mAddReleaseCalled != 0;
293
294 frame.postedTime = d.mPostedTime;
295 frame.requestedPresentTime = d.mRequestedPresentTime;
296 frame.latchTime = d.mLatchTime;
297 frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
298 frame.lastRefreshStartTime = d.mLastRefreshStartTime;
299
300 if (frame.frameNumber == d.mFrameNumber) {
301 // Existing frame. Merge.
302 // Consumer never sends timestamps of fences, only the fences
303 // themselves, so we never need to update the fence timestamps here.
304 applyFenceDelta(&frame.acquireFence, d.mAcquireFence);
305 applyFenceDelta(
306 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
307 applyFenceDelta(&frame.displayPresentFence, d.mDisplayPresentFence);
308 applyFenceDelta(&frame.displayRetireFence, d.mDisplayRetireFence);
309 applyFenceDelta(&frame.releaseFence, d.mReleaseFence);
310 } else {
311 // New frame. Overwrite.
312 frame.frameNumber = d.mFrameNumber;
313
314 frame.gpuCompositionDoneFence = d.mGpuCompositionDoneFence;
315 frame.displayPresentFence = d.mDisplayPresentFence;
316 frame.displayRetireFence = d.mDisplayRetireFence;
317 frame.releaseFence = d.mReleaseFence;
318
319 // Set aquire fence and time at this point.
320 frame.acquireTime = 0;
321 frame.acquireFence = d.mAcquireFence;
322
323 // Reset fence-related timestamps
324 frame.gpuCompositionDoneTime = 0;
325 frame.displayPresentTime = 0;
326 frame.displayRetireTime = 0;
327 frame.releaseTime = 0;
328
329 // The consumer only sends valid frames.
330 frame.valid = true;
Brian Andersond6927fb2016-07-23 23:37:30 -0700331 }
332 }
333}
334
Brian Anderson3890c392016-07-25 12:48:08 -0700335
336// ============================================================================
337// ConsumerFrameEventHistory
338// ============================================================================
339
340ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
341
342void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
343 // Overwrite all fields of the frame with default values unless set here.
344 FrameEvents newTimestamps;
345 newTimestamps.frameNumber = newEntry.frameNumber;
346 newTimestamps.postedTime = newEntry.postedTime;
347 newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
348 newTimestamps.acquireFence = newEntry.acquireFence;
349 newTimestamps.valid = true;
350 mFrames[mQueueOffset] = newTimestamps;
351 mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
352 mFramesDirty[mQueueOffset].setDirty<FrameEvent::ACQUIRE>();
353
354 mQueueOffset = (mQueueOffset + 1) % mFrames.size();
355}
356
357void ConsumerFrameEventHistory::addLatch(
358 uint64_t frameNumber, nsecs_t latchTime) {
359 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
360 if (frame == nullptr) {
361 ALOGE("ConsumerFrameEventHistory::addLatch: Did not find frame.");
362 return;
363 }
364 frame->latchTime = latchTime;
365 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
366}
367
368void ConsumerFrameEventHistory::addPreComposition(
369 uint64_t frameNumber, nsecs_t refreshStartTime) {
370 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
371 if (frame == nullptr) {
372 ALOGE("ConsumerFrameEventHistory::addPreComposition: "
373 "Did not find frame.");
374 return;
375 }
376 frame->lastRefreshStartTime = refreshStartTime;
377 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
378 if (!isValidTimestamp(frame->firstRefreshStartTime)) {
379 frame->firstRefreshStartTime = refreshStartTime;
380 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
381 }
382}
383
384void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
385 sp<Fence> gpuCompositionDone, sp<Fence> displayPresent) {
386 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
387 if (frame == nullptr) {
388 ALOGE("ConsumerFrameEventHistory::addPostComposition: "
389 "Did not find frame.");
390 return;
391 }
392 // Only get GPU and present info for the first composite.
393 if (!frame->addPostCompositeCalled) {
394 frame->addPostCompositeCalled = true;
395 frame->gpuCompositionDoneFence = gpuCompositionDone;
396 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GL_COMPOSITION_DONE>();
397 if (!frame->displayPresentFence->isValid()) {
398 frame->displayPresentFence = displayPresent;
399 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
400 }
401 }
402}
403
404void ConsumerFrameEventHistory::addRetire(
Brian Andersond6927fb2016-07-23 23:37:30 -0700405 uint64_t frameNumber, sp<Fence> displayRetire) {
406 FrameEvents* frame = getFrame(frameNumber, &mRetireOffset);
407 if (frame == nullptr) {
Brian Anderson3890c392016-07-25 12:48:08 -0700408 ALOGE("ConsumerFrameEventHistory::addRetire: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700409 return;
410 }
411 frame->addRetireCalled = true;
412 frame->displayRetireFence = displayRetire;
Brian Anderson3890c392016-07-25 12:48:08 -0700413 mFramesDirty[mRetireOffset].setDirty<FrameEvent::DISPLAY_RETIRE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700414}
415
Brian Anderson3890c392016-07-25 12:48:08 -0700416void ConsumerFrameEventHistory::addRelease(
Brian Andersond6927fb2016-07-23 23:37:30 -0700417 uint64_t frameNumber, sp<Fence> release) {
418 FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
419 if (frame == nullptr) {
Brian Anderson3890c392016-07-25 12:48:08 -0700420 ALOGE("ConsumerFrameEventHistory::addRelease: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700421 return;
422 }
Brian Anderson3890c392016-07-25 12:48:08 -0700423 frame->addReleaseCalled = true;
Brian Andersond6927fb2016-07-23 23:37:30 -0700424 frame->releaseFence = release;
Brian Anderson3890c392016-07-25 12:48:08 -0700425 mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700426}
427
Brian Anderson3890c392016-07-25 12:48:08 -0700428void ConsumerFrameEventHistory::getAndResetDelta(
429 FrameEventHistoryDelta* delta) {
430 delta->mDeltas.reserve(mFramesDirty.size());
431 for (size_t i = 0; i < mFramesDirty.size(); i++) {
432 if (mFramesDirty[i].anyDirty()) {
433 delta->mDeltas.push_back(
434 FrameEventsDelta(i, mFrames[i], mFramesDirty[i]));
435 mFramesDirty[i].reset();
436 }
437 }
438}
439
440
441// ============================================================================
442// FrameEventsDelta
443// ============================================================================
444
445FrameEventsDelta::FrameEventsDelta(
446 size_t index,
447 const FrameEvents& frameTimestamps,
448 const FrameEventDirtyFields& dirtyFields)
449 : mIndex(index),
450 mFrameNumber(frameTimestamps.frameNumber),
451 mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
452 mAddRetireCalled(frameTimestamps.addRetireCalled),
453 mAddReleaseCalled(frameTimestamps.addReleaseCalled),
454 mPostedTime(frameTimestamps.postedTime),
455 mRequestedPresentTime(frameTimestamps.requestedPresentTime),
456 mLatchTime(frameTimestamps.latchTime),
457 mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
458 mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime) {
459 mAcquireFence = dirtyFields.isDirty<FrameEvent::ACQUIRE>() ?
460 frameTimestamps.acquireFence : Fence::NO_FENCE;
461 mGpuCompositionDoneFence =
462 dirtyFields.isDirty<FrameEvent::GL_COMPOSITION_DONE>() ?
463 frameTimestamps.gpuCompositionDoneFence : Fence::NO_FENCE;
464 mDisplayPresentFence = dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>() ?
465 frameTimestamps.displayPresentFence : Fence::NO_FENCE;
466 mDisplayRetireFence = dirtyFields.isDirty<FrameEvent::DISPLAY_RETIRE>() ?
467 frameTimestamps.displayRetireFence : Fence::NO_FENCE;
468 mReleaseFence = dirtyFields.isDirty<FrameEvent::RELEASE>() ?
469 frameTimestamps.releaseFence : Fence::NO_FENCE;
470}
471
472size_t FrameEventsDelta::minFlattenedSize() {
473 constexpr size_t min =
474 sizeof(FrameEventsDelta::mFrameNumber) +
475 sizeof(uint8_t) + // mIndex
476 sizeof(uint8_t) + // mAddPostCompositeCalled
477 sizeof(uint8_t) + // mAddRetireCalled
478 sizeof(uint8_t) + // mAddReleaseCalled
479 sizeof(FrameEventsDelta::mPostedTime) +
480 sizeof(FrameEventsDelta::mRequestedPresentTime) +
481 sizeof(FrameEventsDelta::mLatchTime) +
482 sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
483 sizeof(FrameEventsDelta::mLastRefreshStartTime);
484 return min;
485}
486
487// Flattenable implementation
488size_t FrameEventsDelta::getFlattenedSize() const {
489 auto fences = allFences(this);
490 return minFlattenedSize() +
491 std::accumulate(fences.begin(), fences.end(), size_t(0),
492 [](size_t a, const sp<Fence>* fence) {
493 return a + (*fence)->getFlattenedSize();
494 });
495}
496
497size_t FrameEventsDelta::getFdCount() const {
498 auto fences = allFences(this);
499 return std::accumulate(fences.begin(), fences.end(), size_t(0),
500 [](size_t a, const sp<Fence>* fence) {
501 return a + (*fence)->getFdCount();
502 });
503}
504
505status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
506 size_t& count) const {
507 if (size < getFlattenedSize() || count < getFdCount()) {
508 return NO_MEMORY;
509 }
510
511 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY ||
512 mIndex > std::numeric_limits<uint8_t>::max()) {
513 return BAD_VALUE;
514 }
515
516 FlattenableUtils::write(buffer, size, mFrameNumber);
517
518 // These are static_cast to uint8_t for alignment.
519 FlattenableUtils::write(buffer, size, static_cast<uint8_t>(mIndex));
520 FlattenableUtils::write(
521 buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
522 FlattenableUtils::write(
523 buffer, size, static_cast<uint8_t>(mAddRetireCalled));
524 FlattenableUtils::write(
525 buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
526
527 FlattenableUtils::write(buffer, size, mPostedTime);
528 FlattenableUtils::write(buffer, size, mRequestedPresentTime);
529 FlattenableUtils::write(buffer, size, mLatchTime);
530 FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
531 FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
532
533 // Fences
534 for (auto fence : allFences(this)) {
535 status_t status = (*fence)->flatten(buffer, size, fds, count);
536 if (status != NO_ERROR) {
537 return status;
538 }
539 }
540 return NO_ERROR;
541}
542
543status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
544 int const*& fds, size_t& count) {
545 if (size < minFlattenedSize()) {
546 return NO_MEMORY;
547 }
548
549 FlattenableUtils::read(buffer, size, mFrameNumber);
550
551 // These were written as uint8_t for alignment.
552 uint8_t temp = 0;
553 FlattenableUtils::read(buffer, size, temp);
554 mIndex = temp;
555 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY) {
556 return BAD_VALUE;
557 }
558 FlattenableUtils::read(buffer, size, temp);
559 mAddPostCompositeCalled = static_cast<bool>(temp);
560 FlattenableUtils::read(buffer, size, temp);
561 mAddRetireCalled = static_cast<bool>(temp);
562 FlattenableUtils::read(buffer, size, temp);
563 mAddReleaseCalled = static_cast<bool>(temp);
564
565 FlattenableUtils::read(buffer, size, mPostedTime);
566 FlattenableUtils::read(buffer, size, mRequestedPresentTime);
567 FlattenableUtils::read(buffer, size, mLatchTime);
568 FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
569 FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
570
571 // Fences
572 for (auto fence : allFences(this)) {
573 *fence = new Fence;
574 status_t status = (*fence)->unflatten(buffer, size, fds, count);
575 if (status != NO_ERROR) {
576 return status;
577 }
578 }
579 return NO_ERROR;
580}
581
582
583// ============================================================================
584// FrameEventHistoryDelta
585// ============================================================================
586
587size_t FrameEventHistoryDelta::minFlattenedSize() {
588 return sizeof(uint32_t);
589}
590
591size_t FrameEventHistoryDelta::getFlattenedSize() const {
592 return minFlattenedSize() +
593 std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
594 [](size_t a, const FrameEventsDelta& delta) {
595 return a + delta.getFlattenedSize();
596 });
597}
598
599size_t FrameEventHistoryDelta::getFdCount() const {
600 return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
601 [](size_t a, const FrameEventsDelta& delta) {
602 return a + delta.getFdCount();
603 });
604}
605
606status_t FrameEventHistoryDelta::flatten(
607 void*& buffer, size_t& size, int*& fds, size_t& count) const {
608 if (mDeltas.size() > FrameEventHistory::MAX_FRAME_HISTORY) {
609 return BAD_VALUE;
610 }
611 if (size < getFlattenedSize()) {
612 return NO_MEMORY;
613 }
614
615 FlattenableUtils::write(
616 buffer, size, static_cast<uint32_t>(mDeltas.size()));
617 for (auto& d : mDeltas) {
618 status_t status = d.flatten(buffer, size, fds, count);
619 if (status != NO_ERROR) {
620 return status;
621 }
622 }
623 return NO_ERROR;
624}
625
626status_t FrameEventHistoryDelta::unflatten(
627 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
628 if (size < minFlattenedSize()) {
629 return NO_MEMORY;
630 }
631
632 uint32_t deltaCount = 0;
633 FlattenableUtils::read(buffer, size, deltaCount);
634 if (deltaCount > FrameEventHistory::MAX_FRAME_HISTORY) {
635 return BAD_VALUE;
636 }
637 mDeltas.resize(deltaCount);
638 for (auto& d : mDeltas) {
639 status_t status = d.unflatten(buffer, size, fds, count);
640 if (status != NO_ERROR) {
641 return status;
642 }
643 }
644 return NO_ERROR;
645}
646
647
Brian Andersond6927fb2016-07-23 23:37:30 -0700648} // namespace android