blob: 46ca97470a760300c11c620d4accf9aee7a3093c [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>
21#include <utils/String8.h>
22
23#include <algorithm>
24#include <limits>
Brian Anderson3890c392016-07-25 12:48:08 -070025#include <numeric>
Brian Andersond6927fb2016-07-23 23:37:30 -070026
27namespace android {
28
Brian Andersond6927fb2016-07-23 23:37:30 -070029
30// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -070031// FrameEvents
32// ============================================================================
33
Brian Anderson3890c392016-07-25 12:48:08 -070034bool FrameEvents::hasPostedInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070035 return Fence::isValidTimestamp(postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -070036}
37
38bool FrameEvents::hasRequestedPresentInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070039 return Fence::isValidTimestamp(requestedPresentTime);
Brian Anderson3890c392016-07-25 12:48:08 -070040}
41
42bool FrameEvents::hasLatchInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070043 return Fence::isValidTimestamp(latchTime);
Brian Anderson3890c392016-07-25 12:48:08 -070044}
45
46bool FrameEvents::hasFirstRefreshStartInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070047 return Fence::isValidTimestamp(firstRefreshStartTime);
Brian Anderson3890c392016-07-25 12:48:08 -070048}
49
50bool FrameEvents::hasLastRefreshStartInfo() const {
51 // The last refresh start time may continue to update until a new frame
52 // is latched. We know we have the final value once the release or retire
53 // info is set. See ConsumerFrameEventHistory::addRetire/Release.
54 return addRetireCalled || addReleaseCalled;
55}
56
57bool FrameEvents::hasAcquireInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070058 return acquireFence->isValid();
Brian Anderson3890c392016-07-25 12:48:08 -070059}
60
61bool FrameEvents::hasGpuCompositionDoneInfo() const {
62 // We may not get a gpuCompositionDone in addPostComposite if
63 // client/gles compositing isn't needed.
64 return addPostCompositeCalled;
65}
66
67bool FrameEvents::hasDisplayPresentInfo() const {
68 // We may not get a displayPresent in addPostComposite for HWC1.
69 return addPostCompositeCalled;
70}
71
72bool FrameEvents::hasDisplayRetireInfo() const {
73 // We may not get a displayRetire in addRetire for HWC2.
74 return addRetireCalled;
75}
76
77bool FrameEvents::hasReleaseInfo() const {
78 return addReleaseCalled;
79}
80
Brian Anderson3d4039d2016-09-23 16:31:30 -070081void FrameEvents::checkFencesForCompletion() {
82 acquireFence->getSignalTime();
83 gpuCompositionDoneFence->getSignalTime();
84 displayPresentFence->getSignalTime();
85 displayRetireFence->getSignalTime();
86 releaseFence->getSignalTime();
Brian Andersond6927fb2016-07-23 23:37:30 -070087}
88
Brian Anderson3d4039d2016-09-23 16:31:30 -070089static void dumpFenceTime(String8& outString, const char* name,
90 bool pending, const FenceTime& fenceTime) {
91 outString.appendFormat("--- %s", name);
92 nsecs_t signalTime = fenceTime.getCachedSignalTime();
93 if (Fence::isValidTimestamp(signalTime)) {
94 outString.appendFormat("%" PRId64 "\n", signalTime);
95 } else if (pending || signalTime == Fence::SIGNAL_TIME_PENDING) {
96 outString.appendFormat("Pending\n");
97 } else if (&fenceTime == FenceTime::NO_FENCE.get()){
98 outString.appendFormat("N/A\n");
99 } else {
100 outString.appendFormat("Error\n");
101 }
Brian Andersond6927fb2016-07-23 23:37:30 -0700102}
103
104void FrameEvents::dump(String8& outString) const
105{
106 if (!valid) {
107 return;
108 }
109
110 outString.appendFormat("-- Frame %" PRIu64 "\n", frameNumber);
111 outString.appendFormat("--- Posted \t%" PRId64 "\n", postedTime);
112 outString.appendFormat("--- Req. Present\t%" PRId64 "\n", requestedPresentTime);
113
114 outString.appendFormat("--- Latched \t");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700115 if (Fence::isValidTimestamp(latchTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700116 outString.appendFormat("%" PRId64 "\n", latchTime);
117 } else {
118 outString.appendFormat("Pending\n");
119 }
120
121 outString.appendFormat("--- Refresh (First)\t");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700122 if (Fence::isValidTimestamp(firstRefreshStartTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700123 outString.appendFormat("%" PRId64 "\n", firstRefreshStartTime);
124 } else {
125 outString.appendFormat("Pending\n");
126 }
127
128 outString.appendFormat("--- Refresh (Last)\t");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700129 if (Fence::isValidTimestamp(lastRefreshStartTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700130 outString.appendFormat("%" PRId64 "\n", lastRefreshStartTime);
131 } else {
132 outString.appendFormat("Pending\n");
133 }
134
Brian Anderson3d4039d2016-09-23 16:31:30 -0700135 dumpFenceTime(outString, "Acquire \t",
136 true, *acquireFence);
137 dumpFenceTime(outString, "GPU Composite Done\t",
138 !addPostCompositeCalled, *gpuCompositionDoneFence);
139 dumpFenceTime(outString, "Display Present \t",
140 !addPostCompositeCalled, *displayPresentFence);
141 dumpFenceTime(outString, "Display Retire \t",
142 !addRetireCalled, *displayRetireFence);
143 dumpFenceTime(outString, "Release \t",
144 true, *releaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700145}
146
147
148// ============================================================================
149// FrameEventHistory
150// ============================================================================
151
152namespace {
153
154struct FrameNumberEqual {
155 FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
156 bool operator()(const FrameEvents& frame) {
157 return frame.valid && mFrameNumber == frame.frameNumber;
158 }
159 const uint64_t mFrameNumber;
160};
161
162} // namespace
163
Brian Anderson3890c392016-07-25 12:48:08 -0700164FrameEventHistory::~FrameEventHistory() = default;
Brian Andersond6927fb2016-07-23 23:37:30 -0700165
166FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber) {
167 auto frame = std::find_if(
168 mFrames.begin(), mFrames.end(), FrameNumberEqual(frameNumber));
169 return frame == mFrames.end() ? nullptr : &(*frame);
170}
171
172FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber, size_t* iHint) {
173 *iHint = std::min(*iHint, mFrames.size());
174 auto hint = mFrames.begin() + *iHint;
175 auto frame = std::find_if(
176 hint, mFrames.end(), FrameNumberEqual(frameNumber));
177 if (frame == mFrames.end()) {
178 frame = std::find_if(
179 mFrames.begin(), hint, FrameNumberEqual(frameNumber));
180 if (frame == hint) {
181 return nullptr;
182 }
183 }
184 *iHint = static_cast<size_t>(std::distance(mFrames.begin(), frame));
185 return &(*frame);
186}
187
188void FrameEventHistory::checkFencesForCompletion() {
189 for (auto& frame : mFrames) {
190 frame.checkFencesForCompletion();
191 }
192}
193
194// Uses !|valid| as the MSB.
195static bool FrameNumberLessThan(
196 const FrameEvents& lhs, const FrameEvents& rhs) {
197 if (lhs.valid == rhs.valid) {
198 return lhs.frameNumber < rhs.frameNumber;
199 }
200 return lhs.valid;
201}
202
203void FrameEventHistory::dump(String8& outString) const {
204 auto earliestFrame = std::min_element(
205 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
206 if (!earliestFrame->valid) {
207 outString.appendFormat("-- N/A\n");
208 return;
209 }
210 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
211 frame->dump(outString);
212 }
213 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
214 frame->dump(outString);
215 }
216}
217
Brian Andersond6927fb2016-07-23 23:37:30 -0700218
Brian Anderson3890c392016-07-25 12:48:08 -0700219// ============================================================================
220// ProducerFrameEventHistory
221// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -0700222
Brian Anderson3890c392016-07-25 12:48:08 -0700223ProducerFrameEventHistory::~ProducerFrameEventHistory() = default;
224
225void ProducerFrameEventHistory::updateAcquireFence(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700226 uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) {
Brian Anderson3890c392016-07-25 12:48:08 -0700227 FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
Brian Andersond6927fb2016-07-23 23:37:30 -0700228 if (frame == nullptr) {
Brian Anderson3890c392016-07-25 12:48:08 -0700229 ALOGE("ProducerFrameEventHistory::updateAcquireFence: "
230 "Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700231 return;
232 }
233
Brian Anderson3890c392016-07-25 12:48:08 -0700234 if (acquire->isValid()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700235 mAcquireTimeline.push(acquire);
236 frame->acquireFence = std::move(acquire);
Brian Anderson3890c392016-07-25 12:48:08 -0700237 } else {
238 // If there isn't an acquire fence, assume that buffer was
239 // ready for the consumer when posted.
Brian Anderson3d4039d2016-09-23 16:31:30 -0700240 frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700241 }
242}
243
Brian Anderson3890c392016-07-25 12:48:08 -0700244void ProducerFrameEventHistory::applyDelta(
245 const FrameEventHistoryDelta& delta) {
246 for (auto& d : delta.mDeltas) {
247 // Avoid out-of-bounds access.
248 if (d.mIndex >= mFrames.size()) {
249 ALOGE("ProducerFrameEventHistory::applyDelta: Bad index.");
250 return;
251 }
252
253 FrameEvents& frame = mFrames[d.mIndex];
254
255 frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
256 frame.addRetireCalled = d.mAddRetireCalled != 0;
257 frame.addReleaseCalled = d.mAddReleaseCalled != 0;
258
259 frame.postedTime = d.mPostedTime;
260 frame.requestedPresentTime = d.mRequestedPresentTime;
261 frame.latchTime = d.mLatchTime;
262 frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
263 frame.lastRefreshStartTime = d.mLastRefreshStartTime;
264
Brian Anderson3d4039d2016-09-23 16:31:30 -0700265 if (frame.frameNumber != d.mFrameNumber) {
266 // We got a new frame. Initialize some of the fields.
Brian Anderson3890c392016-07-25 12:48:08 -0700267 frame.frameNumber = d.mFrameNumber;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700268 frame.acquireFence = FenceTime::NO_FENCE;
269 frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
270 frame.displayPresentFence = FenceTime::NO_FENCE;
271 frame.displayRetireFence = FenceTime::NO_FENCE;
272 frame.releaseFence = FenceTime::NO_FENCE;
Brian Anderson3890c392016-07-25 12:48:08 -0700273 // The consumer only sends valid frames.
274 frame.valid = true;
Brian Andersond6927fb2016-07-23 23:37:30 -0700275 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700276
277 applyFenceDelta(&mGpuCompositionDoneTimeline,
278 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
279 applyFenceDelta(&mPresentTimeline,
280 &frame.displayPresentFence, d.mDisplayPresentFence);
281 applyFenceDelta(&mRetireTimeline,
282 &frame.displayRetireFence, d.mDisplayRetireFence);
283 applyFenceDelta(&mReleaseTimeline,
284 &frame.releaseFence, d.mReleaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700285 }
286}
287
Brian Anderson3d4039d2016-09-23 16:31:30 -0700288void ProducerFrameEventHistory::updateSignalTimes() {
289 mAcquireTimeline.updateSignalTimes();
290 mGpuCompositionDoneTimeline.updateSignalTimes();
291 mPresentTimeline.updateSignalTimes();
292 mRetireTimeline.updateSignalTimes();
293 mReleaseTimeline.updateSignalTimes();
294}
295
Brian Anderson3da8d272016-07-28 16:20:47 -0700296void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
297 std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
298 if (CC_UNLIKELY(dst == nullptr)) {
299 ALOGE("applyFenceDelta: dst is null.");
300 return;
301 }
302
303 switch (src.state) {
304 case FenceTime::Snapshot::State::EMPTY:
305 return;
306 case FenceTime::Snapshot::State::FENCE:
307 if (CC_UNLIKELY((*dst)->isValid())) {
308 ALOGE("applyFenceDelta: Unexpected fence.");
309 }
310 *dst = createFenceTime(src.fence);
311 timeline->push(*dst);
312 return;
313 case FenceTime::Snapshot::State::SIGNAL_TIME:
314 if ((*dst)->isValid()) {
315 (*dst)->applyTrustedSnapshot(src);
316 } else {
317 *dst = std::make_shared<FenceTime>(src.signalTime);
318 }
319 return;
320 }
321}
322
323std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
324 const sp<Fence>& fence) const {
325 return std::make_shared<FenceTime>(fence);
326}
327
Brian Anderson3890c392016-07-25 12:48:08 -0700328
329// ============================================================================
330// ConsumerFrameEventHistory
331// ============================================================================
332
333ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
334
335void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
336 // Overwrite all fields of the frame with default values unless set here.
337 FrameEvents newTimestamps;
338 newTimestamps.frameNumber = newEntry.frameNumber;
339 newTimestamps.postedTime = newEntry.postedTime;
340 newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
341 newTimestamps.acquireFence = newEntry.acquireFence;
342 newTimestamps.valid = true;
343 mFrames[mQueueOffset] = newTimestamps;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700344
345 // Note: We avoid sending the acquire fence back to the caller since
346 // they have the original one already, so there is no need to set the
347 // acquire dirty bit.
Brian Anderson3890c392016-07-25 12:48:08 -0700348 mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
Brian Anderson3890c392016-07-25 12:48:08 -0700349
350 mQueueOffset = (mQueueOffset + 1) % mFrames.size();
351}
352
353void ConsumerFrameEventHistory::addLatch(
354 uint64_t frameNumber, nsecs_t latchTime) {
355 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
356 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800357 ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700358 return;
359 }
360 frame->latchTime = latchTime;
361 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
362}
363
364void ConsumerFrameEventHistory::addPreComposition(
365 uint64_t frameNumber, nsecs_t refreshStartTime) {
366 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
367 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800368 ALOGE_IF(mProducerWantsEvents,
369 "addPreComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700370 return;
371 }
372 frame->lastRefreshStartTime = refreshStartTime;
373 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
Brian Anderson3d4039d2016-09-23 16:31:30 -0700374 if (!Fence::isValidTimestamp(frame->firstRefreshStartTime)) {
Brian Anderson3890c392016-07-25 12:48:08 -0700375 frame->firstRefreshStartTime = refreshStartTime;
376 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
377 }
378}
379
380void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
Brian Anderson3d4039d2016-09-23 16:31:30 -0700381 const std::shared_ptr<FenceTime>& gpuCompositionDone,
382 const std::shared_ptr<FenceTime>& displayPresent) {
Brian Anderson3890c392016-07-25 12:48:08 -0700383 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
384 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800385 ALOGE_IF(mProducerWantsEvents,
386 "addPostComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700387 return;
388 }
389 // Only get GPU and present info for the first composite.
390 if (!frame->addPostCompositeCalled) {
391 frame->addPostCompositeCalled = true;
392 frame->gpuCompositionDoneFence = gpuCompositionDone;
393 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GL_COMPOSITION_DONE>();
394 if (!frame->displayPresentFence->isValid()) {
395 frame->displayPresentFence = displayPresent;
396 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
397 }
398 }
399}
400
401void ConsumerFrameEventHistory::addRetire(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700402 uint64_t frameNumber, const std::shared_ptr<FenceTime>& displayRetire) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700403 FrameEvents* frame = getFrame(frameNumber, &mRetireOffset);
404 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800405 ALOGE_IF(mProducerWantsEvents, "addRetire: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700406 return;
407 }
408 frame->addRetireCalled = true;
409 frame->displayRetireFence = displayRetire;
Brian Anderson3890c392016-07-25 12:48:08 -0700410 mFramesDirty[mRetireOffset].setDirty<FrameEvent::DISPLAY_RETIRE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700411}
412
Brian Anderson3890c392016-07-25 12:48:08 -0700413void ConsumerFrameEventHistory::addRelease(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700414 uint64_t frameNumber, std::shared_ptr<FenceTime>&& release) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700415 FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
416 if (frame == nullptr) {
Brian Anderson3890c392016-07-25 12:48:08 -0700417 ALOGE("ConsumerFrameEventHistory::addRelease: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700418 return;
419 }
Brian Anderson3890c392016-07-25 12:48:08 -0700420 frame->addReleaseCalled = true;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700421 frame->releaseFence = std::move(release);
Brian Anderson3890c392016-07-25 12:48:08 -0700422 mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700423}
424
Brian Anderson3d4039d2016-09-23 16:31:30 -0700425void ConsumerFrameEventHistory::getFrameDelta(
426 FrameEventHistoryDelta* delta,
427 const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800428 mProducerWantsEvents = true;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700429 size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
430 if (mFramesDirty[i].anyDirty()) {
431 delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
432 mFramesDirty[i].reset();
433 }
434}
435
Brian Anderson3890c392016-07-25 12:48:08 -0700436void ConsumerFrameEventHistory::getAndResetDelta(
437 FrameEventHistoryDelta* delta) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700438 // Write these in order of frame number so that it is easy to
439 // add them to a FenceTimeline in the proper order producer side.
Brian Anderson3890c392016-07-25 12:48:08 -0700440 delta->mDeltas.reserve(mFramesDirty.size());
Brian Anderson3d4039d2016-09-23 16:31:30 -0700441 auto earliestFrame = std::min_element(
442 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
443 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
444 getFrameDelta(delta, frame);
445 }
446 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
447 getFrameDelta(delta, frame);
Brian Anderson3890c392016-07-25 12:48:08 -0700448 }
449}
450
451
452// ============================================================================
453// FrameEventsDelta
454// ============================================================================
455
456FrameEventsDelta::FrameEventsDelta(
457 size_t index,
458 const FrameEvents& frameTimestamps,
459 const FrameEventDirtyFields& dirtyFields)
460 : mIndex(index),
461 mFrameNumber(frameTimestamps.frameNumber),
462 mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
463 mAddRetireCalled(frameTimestamps.addRetireCalled),
464 mAddReleaseCalled(frameTimestamps.addReleaseCalled),
465 mPostedTime(frameTimestamps.postedTime),
466 mRequestedPresentTime(frameTimestamps.requestedPresentTime),
467 mLatchTime(frameTimestamps.latchTime),
468 mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
469 mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700470 if (dirtyFields.isDirty<FrameEvent::GL_COMPOSITION_DONE>()) {
471 mGpuCompositionDoneFence =
472 frameTimestamps.gpuCompositionDoneFence->getSnapshot();
473 }
474 if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
475 mDisplayPresentFence =
476 frameTimestamps.displayPresentFence->getSnapshot();
477 }
478 if (dirtyFields.isDirty<FrameEvent::DISPLAY_RETIRE>()) {
479 mDisplayRetireFence = frameTimestamps.displayRetireFence->getSnapshot();
480 }
481 if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
482 mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
483 }
Brian Anderson3890c392016-07-25 12:48:08 -0700484}
485
486size_t FrameEventsDelta::minFlattenedSize() {
487 constexpr size_t min =
488 sizeof(FrameEventsDelta::mFrameNumber) +
489 sizeof(uint8_t) + // mIndex
490 sizeof(uint8_t) + // mAddPostCompositeCalled
491 sizeof(uint8_t) + // mAddRetireCalled
492 sizeof(uint8_t) + // mAddReleaseCalled
493 sizeof(FrameEventsDelta::mPostedTime) +
494 sizeof(FrameEventsDelta::mRequestedPresentTime) +
495 sizeof(FrameEventsDelta::mLatchTime) +
496 sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
497 sizeof(FrameEventsDelta::mLastRefreshStartTime);
498 return min;
499}
500
501// Flattenable implementation
502size_t FrameEventsDelta::getFlattenedSize() const {
503 auto fences = allFences(this);
504 return minFlattenedSize() +
505 std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700506 [](size_t a, const FenceTime::Snapshot* fence) {
507 return a + fence->getFlattenedSize();
Brian Anderson3890c392016-07-25 12:48:08 -0700508 });
509}
510
511size_t FrameEventsDelta::getFdCount() const {
512 auto fences = allFences(this);
513 return std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700514 [](size_t a, const FenceTime::Snapshot* fence) {
515 return a + fence->getFdCount();
Brian Anderson3890c392016-07-25 12:48:08 -0700516 });
517}
518
519status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
520 size_t& count) const {
521 if (size < getFlattenedSize() || count < getFdCount()) {
522 return NO_MEMORY;
523 }
524
525 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY ||
526 mIndex > std::numeric_limits<uint8_t>::max()) {
527 return BAD_VALUE;
528 }
529
530 FlattenableUtils::write(buffer, size, mFrameNumber);
531
532 // These are static_cast to uint8_t for alignment.
533 FlattenableUtils::write(buffer, size, static_cast<uint8_t>(mIndex));
534 FlattenableUtils::write(
535 buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
536 FlattenableUtils::write(
537 buffer, size, static_cast<uint8_t>(mAddRetireCalled));
538 FlattenableUtils::write(
539 buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
540
541 FlattenableUtils::write(buffer, size, mPostedTime);
542 FlattenableUtils::write(buffer, size, mRequestedPresentTime);
543 FlattenableUtils::write(buffer, size, mLatchTime);
544 FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
545 FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
546
547 // Fences
548 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700549 status_t status = fence->flatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700550 if (status != NO_ERROR) {
551 return status;
552 }
553 }
554 return NO_ERROR;
555}
556
557status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
558 int const*& fds, size_t& count) {
559 if (size < minFlattenedSize()) {
560 return NO_MEMORY;
561 }
562
563 FlattenableUtils::read(buffer, size, mFrameNumber);
564
565 // These were written as uint8_t for alignment.
566 uint8_t temp = 0;
567 FlattenableUtils::read(buffer, size, temp);
568 mIndex = temp;
569 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY) {
570 return BAD_VALUE;
571 }
572 FlattenableUtils::read(buffer, size, temp);
573 mAddPostCompositeCalled = static_cast<bool>(temp);
574 FlattenableUtils::read(buffer, size, temp);
575 mAddRetireCalled = static_cast<bool>(temp);
576 FlattenableUtils::read(buffer, size, temp);
577 mAddReleaseCalled = static_cast<bool>(temp);
578
579 FlattenableUtils::read(buffer, size, mPostedTime);
580 FlattenableUtils::read(buffer, size, mRequestedPresentTime);
581 FlattenableUtils::read(buffer, size, mLatchTime);
582 FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
583 FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
584
585 // Fences
586 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700587 status_t status = fence->unflatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700588 if (status != NO_ERROR) {
589 return status;
590 }
591 }
592 return NO_ERROR;
593}
594
595
596// ============================================================================
597// FrameEventHistoryDelta
598// ============================================================================
599
Brian Anderson3d4039d2016-09-23 16:31:30 -0700600FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
601 FrameEventHistoryDelta&& src) {
602 if (CC_UNLIKELY(!mDeltas.empty())) {
603 ALOGE("FrameEventHistoryDelta: Clobbering history.");
604 }
605 mDeltas = std::move(src.mDeltas);
606 ALOGE_IF(src.mDeltas.empty(), "Source mDeltas not empty.");
607 return *this;
608}
609
Brian Anderson3890c392016-07-25 12:48:08 -0700610size_t FrameEventHistoryDelta::minFlattenedSize() {
611 return sizeof(uint32_t);
612}
613
614size_t FrameEventHistoryDelta::getFlattenedSize() const {
615 return minFlattenedSize() +
616 std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
617 [](size_t a, const FrameEventsDelta& delta) {
618 return a + delta.getFlattenedSize();
619 });
620}
621
622size_t FrameEventHistoryDelta::getFdCount() const {
623 return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
624 [](size_t a, const FrameEventsDelta& delta) {
625 return a + delta.getFdCount();
626 });
627}
628
629status_t FrameEventHistoryDelta::flatten(
630 void*& buffer, size_t& size, int*& fds, size_t& count) const {
631 if (mDeltas.size() > FrameEventHistory::MAX_FRAME_HISTORY) {
632 return BAD_VALUE;
633 }
634 if (size < getFlattenedSize()) {
635 return NO_MEMORY;
636 }
637
638 FlattenableUtils::write(
639 buffer, size, static_cast<uint32_t>(mDeltas.size()));
640 for (auto& d : mDeltas) {
641 status_t status = d.flatten(buffer, size, fds, count);
642 if (status != NO_ERROR) {
643 return status;
644 }
645 }
646 return NO_ERROR;
647}
648
649status_t FrameEventHistoryDelta::unflatten(
650 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
651 if (size < minFlattenedSize()) {
652 return NO_MEMORY;
653 }
654
655 uint32_t deltaCount = 0;
656 FlattenableUtils::read(buffer, size, deltaCount);
657 if (deltaCount > FrameEventHistory::MAX_FRAME_HISTORY) {
658 return BAD_VALUE;
659 }
660 mDeltas.resize(deltaCount);
661 for (auto& d : mDeltas) {
662 status_t status = d.unflatten(buffer, size, fds, count);
663 if (status != NO_ERROR) {
664 return status;
665 }
666 }
667 return NO_ERROR;
668}
669
670
Brian Andersond6927fb2016-07-23 23:37:30 -0700671} // namespace android