blob: a6fa38aae5932da160ce00f2b2e02404ec5e88d7 [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
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800238nsecs_t ProducerFrameEventHistory::snapToNextTick(
239 nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval) {
240 nsecs_t tickOffset = (tickPhase - timestamp) % tickInterval;
241 // Integer modulo rounds towards 0 and not -inf before taking the remainder,
242 // so adjust the offset if it is negative.
243 if (tickOffset < 0) {
244 tickOffset += tickInterval;
245 }
246 return timestamp + tickOffset;
247}
248
249nsecs_t ProducerFrameEventHistory::getNextCompositeDeadline(
250 const nsecs_t now) const{
251 return snapToNextTick(
252 now, mCompositorTiming.deadline, mCompositorTiming.interval);
253}
254
Brian Anderson3890c392016-07-25 12:48:08 -0700255void ProducerFrameEventHistory::updateAcquireFence(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700256 uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) {
Brian Anderson3890c392016-07-25 12:48:08 -0700257 FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
Brian Andersond6927fb2016-07-23 23:37:30 -0700258 if (frame == nullptr) {
Brian Anderson3890c392016-07-25 12:48:08 -0700259 ALOGE("ProducerFrameEventHistory::updateAcquireFence: "
260 "Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700261 return;
262 }
263
Brian Anderson3890c392016-07-25 12:48:08 -0700264 if (acquire->isValid()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700265 mAcquireTimeline.push(acquire);
266 frame->acquireFence = std::move(acquire);
Brian Anderson3890c392016-07-25 12:48:08 -0700267 } else {
268 // If there isn't an acquire fence, assume that buffer was
269 // ready for the consumer when posted.
Brian Anderson3d4039d2016-09-23 16:31:30 -0700270 frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700271 }
272}
273
Brian Anderson3890c392016-07-25 12:48:08 -0700274void ProducerFrameEventHistory::applyDelta(
275 const FrameEventHistoryDelta& delta) {
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800276 mCompositorTiming = delta.mCompositorTiming;
277
Brian Anderson3890c392016-07-25 12:48:08 -0700278 for (auto& d : delta.mDeltas) {
279 // Avoid out-of-bounds access.
280 if (d.mIndex >= mFrames.size()) {
281 ALOGE("ProducerFrameEventHistory::applyDelta: Bad index.");
282 return;
283 }
284
285 FrameEvents& frame = mFrames[d.mIndex];
286
287 frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
288 frame.addRetireCalled = d.mAddRetireCalled != 0;
289 frame.addReleaseCalled = d.mAddReleaseCalled != 0;
290
291 frame.postedTime = d.mPostedTime;
292 frame.requestedPresentTime = d.mRequestedPresentTime;
293 frame.latchTime = d.mLatchTime;
294 frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
295 frame.lastRefreshStartTime = d.mLastRefreshStartTime;
Brian Andersonf6386862016-10-31 16:34:13 -0700296 frame.dequeueReadyTime = d.mDequeueReadyTime;
Brian Anderson3890c392016-07-25 12:48:08 -0700297
Brian Anderson3d4039d2016-09-23 16:31:30 -0700298 if (frame.frameNumber != d.mFrameNumber) {
299 // We got a new frame. Initialize some of the fields.
Brian Anderson3890c392016-07-25 12:48:08 -0700300 frame.frameNumber = d.mFrameNumber;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700301 frame.acquireFence = FenceTime::NO_FENCE;
302 frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
303 frame.displayPresentFence = FenceTime::NO_FENCE;
304 frame.displayRetireFence = FenceTime::NO_FENCE;
305 frame.releaseFence = FenceTime::NO_FENCE;
Brian Anderson3890c392016-07-25 12:48:08 -0700306 // The consumer only sends valid frames.
307 frame.valid = true;
Brian Andersond6927fb2016-07-23 23:37:30 -0700308 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700309
310 applyFenceDelta(&mGpuCompositionDoneTimeline,
311 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
312 applyFenceDelta(&mPresentTimeline,
313 &frame.displayPresentFence, d.mDisplayPresentFence);
314 applyFenceDelta(&mRetireTimeline,
315 &frame.displayRetireFence, d.mDisplayRetireFence);
316 applyFenceDelta(&mReleaseTimeline,
317 &frame.releaseFence, d.mReleaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700318 }
319}
320
Brian Anderson3d4039d2016-09-23 16:31:30 -0700321void ProducerFrameEventHistory::updateSignalTimes() {
322 mAcquireTimeline.updateSignalTimes();
323 mGpuCompositionDoneTimeline.updateSignalTimes();
324 mPresentTimeline.updateSignalTimes();
325 mRetireTimeline.updateSignalTimes();
326 mReleaseTimeline.updateSignalTimes();
327}
328
Brian Anderson3da8d272016-07-28 16:20:47 -0700329void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
330 std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
331 if (CC_UNLIKELY(dst == nullptr)) {
332 ALOGE("applyFenceDelta: dst is null.");
333 return;
334 }
335
336 switch (src.state) {
337 case FenceTime::Snapshot::State::EMPTY:
338 return;
339 case FenceTime::Snapshot::State::FENCE:
340 if (CC_UNLIKELY((*dst)->isValid())) {
341 ALOGE("applyFenceDelta: Unexpected fence.");
342 }
343 *dst = createFenceTime(src.fence);
344 timeline->push(*dst);
345 return;
346 case FenceTime::Snapshot::State::SIGNAL_TIME:
347 if ((*dst)->isValid()) {
348 (*dst)->applyTrustedSnapshot(src);
349 } else {
350 *dst = std::make_shared<FenceTime>(src.signalTime);
351 }
352 return;
353 }
354}
355
356std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
357 const sp<Fence>& fence) const {
358 return std::make_shared<FenceTime>(fence);
359}
360
Brian Anderson3890c392016-07-25 12:48:08 -0700361
362// ============================================================================
363// ConsumerFrameEventHistory
364// ============================================================================
365
366ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
367
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800368void ConsumerFrameEventHistory::initializeCompositorTiming(
369 const CompositorTiming& compositorTiming) {
370 mCompositorTiming = compositorTiming;
371}
372
Brian Anderson3890c392016-07-25 12:48:08 -0700373void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
374 // Overwrite all fields of the frame with default values unless set here.
375 FrameEvents newTimestamps;
376 newTimestamps.frameNumber = newEntry.frameNumber;
377 newTimestamps.postedTime = newEntry.postedTime;
378 newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
379 newTimestamps.acquireFence = newEntry.acquireFence;
380 newTimestamps.valid = true;
381 mFrames[mQueueOffset] = newTimestamps;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700382
383 // Note: We avoid sending the acquire fence back to the caller since
384 // they have the original one already, so there is no need to set the
385 // acquire dirty bit.
Brian Anderson3890c392016-07-25 12:48:08 -0700386 mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
Brian Anderson3890c392016-07-25 12:48:08 -0700387
388 mQueueOffset = (mQueueOffset + 1) % mFrames.size();
389}
390
391void ConsumerFrameEventHistory::addLatch(
392 uint64_t frameNumber, nsecs_t latchTime) {
393 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
394 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800395 ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700396 return;
397 }
398 frame->latchTime = latchTime;
399 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
400}
401
402void ConsumerFrameEventHistory::addPreComposition(
403 uint64_t frameNumber, nsecs_t refreshStartTime) {
404 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
405 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800406 ALOGE_IF(mProducerWantsEvents,
407 "addPreComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700408 return;
409 }
410 frame->lastRefreshStartTime = refreshStartTime;
411 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
Brian Anderson3d4039d2016-09-23 16:31:30 -0700412 if (!Fence::isValidTimestamp(frame->firstRefreshStartTime)) {
Brian Anderson3890c392016-07-25 12:48:08 -0700413 frame->firstRefreshStartTime = refreshStartTime;
414 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
415 }
416}
417
418void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
Brian Anderson3d4039d2016-09-23 16:31:30 -0700419 const std::shared_ptr<FenceTime>& gpuCompositionDone,
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800420 const std::shared_ptr<FenceTime>& displayPresent,
421 const CompositorTiming& compositorTiming) {
422 mCompositorTiming = compositorTiming;
423
Brian Anderson3890c392016-07-25 12:48:08 -0700424 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
425 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800426 ALOGE_IF(mProducerWantsEvents,
427 "addPostComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700428 return;
429 }
430 // Only get GPU and present info for the first composite.
431 if (!frame->addPostCompositeCalled) {
432 frame->addPostCompositeCalled = true;
433 frame->gpuCompositionDoneFence = gpuCompositionDone;
434 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GL_COMPOSITION_DONE>();
435 if (!frame->displayPresentFence->isValid()) {
436 frame->displayPresentFence = displayPresent;
437 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
438 }
439 }
440}
441
442void ConsumerFrameEventHistory::addRetire(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700443 uint64_t frameNumber, const std::shared_ptr<FenceTime>& displayRetire) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700444 FrameEvents* frame = getFrame(frameNumber, &mRetireOffset);
445 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800446 ALOGE_IF(mProducerWantsEvents, "addRetire: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700447 return;
448 }
449 frame->addRetireCalled = true;
450 frame->displayRetireFence = displayRetire;
Brian Anderson3890c392016-07-25 12:48:08 -0700451 mFramesDirty[mRetireOffset].setDirty<FrameEvent::DISPLAY_RETIRE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700452}
453
Brian Andersonf6386862016-10-31 16:34:13 -0700454void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber,
455 nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700456 FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
457 if (frame == nullptr) {
Brian Anderson3890c392016-07-25 12:48:08 -0700458 ALOGE("ConsumerFrameEventHistory::addRelease: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700459 return;
460 }
Brian Anderson3890c392016-07-25 12:48:08 -0700461 frame->addReleaseCalled = true;
Brian Andersonf6386862016-10-31 16:34:13 -0700462 frame->dequeueReadyTime = dequeueReadyTime;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700463 frame->releaseFence = std::move(release);
Brian Anderson3890c392016-07-25 12:48:08 -0700464 mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700465}
466
Brian Anderson3d4039d2016-09-23 16:31:30 -0700467void ConsumerFrameEventHistory::getFrameDelta(
468 FrameEventHistoryDelta* delta,
469 const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800470 mProducerWantsEvents = true;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700471 size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
472 if (mFramesDirty[i].anyDirty()) {
473 delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
474 mFramesDirty[i].reset();
475 }
476}
477
Brian Anderson3890c392016-07-25 12:48:08 -0700478void ConsumerFrameEventHistory::getAndResetDelta(
479 FrameEventHistoryDelta* delta) {
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800480 delta->mCompositorTiming = mCompositorTiming;
481
Brian Anderson3d4039d2016-09-23 16:31:30 -0700482 // Write these in order of frame number so that it is easy to
483 // add them to a FenceTimeline in the proper order producer side.
Brian Anderson3890c392016-07-25 12:48:08 -0700484 delta->mDeltas.reserve(mFramesDirty.size());
Brian Anderson3d4039d2016-09-23 16:31:30 -0700485 auto earliestFrame = std::min_element(
486 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
487 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
488 getFrameDelta(delta, frame);
489 }
490 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
491 getFrameDelta(delta, frame);
Brian Anderson3890c392016-07-25 12:48:08 -0700492 }
493}
494
495
496// ============================================================================
497// FrameEventsDelta
498// ============================================================================
499
500FrameEventsDelta::FrameEventsDelta(
501 size_t index,
502 const FrameEvents& frameTimestamps,
503 const FrameEventDirtyFields& dirtyFields)
504 : mIndex(index),
505 mFrameNumber(frameTimestamps.frameNumber),
506 mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
507 mAddRetireCalled(frameTimestamps.addRetireCalled),
508 mAddReleaseCalled(frameTimestamps.addReleaseCalled),
509 mPostedTime(frameTimestamps.postedTime),
510 mRequestedPresentTime(frameTimestamps.requestedPresentTime),
511 mLatchTime(frameTimestamps.latchTime),
512 mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
Brian Andersonf6386862016-10-31 16:34:13 -0700513 mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime),
514 mDequeueReadyTime(frameTimestamps.dequeueReadyTime) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700515 if (dirtyFields.isDirty<FrameEvent::GL_COMPOSITION_DONE>()) {
516 mGpuCompositionDoneFence =
517 frameTimestamps.gpuCompositionDoneFence->getSnapshot();
518 }
519 if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
520 mDisplayPresentFence =
521 frameTimestamps.displayPresentFence->getSnapshot();
522 }
523 if (dirtyFields.isDirty<FrameEvent::DISPLAY_RETIRE>()) {
524 mDisplayRetireFence = frameTimestamps.displayRetireFence->getSnapshot();
525 }
526 if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
527 mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
528 }
Brian Anderson3890c392016-07-25 12:48:08 -0700529}
530
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800531constexpr size_t FrameEventsDelta::minFlattenedSize() {
532 return sizeof(FrameEventsDelta::mFrameNumber) +
Brian Anderson3890c392016-07-25 12:48:08 -0700533 sizeof(uint8_t) + // mIndex
534 sizeof(uint8_t) + // mAddPostCompositeCalled
535 sizeof(uint8_t) + // mAddRetireCalled
536 sizeof(uint8_t) + // mAddReleaseCalled
537 sizeof(FrameEventsDelta::mPostedTime) +
538 sizeof(FrameEventsDelta::mRequestedPresentTime) +
539 sizeof(FrameEventsDelta::mLatchTime) +
540 sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
Brian Andersonf6386862016-10-31 16:34:13 -0700541 sizeof(FrameEventsDelta::mLastRefreshStartTime) +
542 sizeof(FrameEventsDelta::mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700543}
544
545// Flattenable implementation
546size_t FrameEventsDelta::getFlattenedSize() const {
547 auto fences = allFences(this);
548 return minFlattenedSize() +
549 std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700550 [](size_t a, const FenceTime::Snapshot* fence) {
551 return a + fence->getFlattenedSize();
Brian Anderson3890c392016-07-25 12:48:08 -0700552 });
553}
554
555size_t FrameEventsDelta::getFdCount() const {
556 auto fences = allFences(this);
557 return std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700558 [](size_t a, const FenceTime::Snapshot* fence) {
559 return a + fence->getFdCount();
Brian Anderson3890c392016-07-25 12:48:08 -0700560 });
561}
562
563status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
564 size_t& count) const {
565 if (size < getFlattenedSize() || count < getFdCount()) {
566 return NO_MEMORY;
567 }
568
569 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY ||
570 mIndex > std::numeric_limits<uint8_t>::max()) {
571 return BAD_VALUE;
572 }
573
574 FlattenableUtils::write(buffer, size, mFrameNumber);
575
576 // These are static_cast to uint8_t for alignment.
577 FlattenableUtils::write(buffer, size, static_cast<uint8_t>(mIndex));
578 FlattenableUtils::write(
579 buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
580 FlattenableUtils::write(
581 buffer, size, static_cast<uint8_t>(mAddRetireCalled));
582 FlattenableUtils::write(
583 buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
584
585 FlattenableUtils::write(buffer, size, mPostedTime);
586 FlattenableUtils::write(buffer, size, mRequestedPresentTime);
587 FlattenableUtils::write(buffer, size, mLatchTime);
588 FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
589 FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700590 FlattenableUtils::write(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700591
592 // Fences
593 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700594 status_t status = fence->flatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700595 if (status != NO_ERROR) {
596 return status;
597 }
598 }
599 return NO_ERROR;
600}
601
602status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
603 int const*& fds, size_t& count) {
604 if (size < minFlattenedSize()) {
605 return NO_MEMORY;
606 }
607
608 FlattenableUtils::read(buffer, size, mFrameNumber);
609
610 // These were written as uint8_t for alignment.
611 uint8_t temp = 0;
612 FlattenableUtils::read(buffer, size, temp);
613 mIndex = temp;
614 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY) {
615 return BAD_VALUE;
616 }
617 FlattenableUtils::read(buffer, size, temp);
618 mAddPostCompositeCalled = static_cast<bool>(temp);
619 FlattenableUtils::read(buffer, size, temp);
620 mAddRetireCalled = static_cast<bool>(temp);
621 FlattenableUtils::read(buffer, size, temp);
622 mAddReleaseCalled = static_cast<bool>(temp);
623
624 FlattenableUtils::read(buffer, size, mPostedTime);
625 FlattenableUtils::read(buffer, size, mRequestedPresentTime);
626 FlattenableUtils::read(buffer, size, mLatchTime);
627 FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
628 FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700629 FlattenableUtils::read(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700630
631 // Fences
632 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700633 status_t status = fence->unflatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700634 if (status != NO_ERROR) {
635 return status;
636 }
637 }
638 return NO_ERROR;
639}
640
641
642// ============================================================================
643// FrameEventHistoryDelta
644// ============================================================================
645
Brian Anderson3d4039d2016-09-23 16:31:30 -0700646FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
647 FrameEventHistoryDelta&& src) {
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800648 mCompositorTiming = src.mCompositorTiming;
649
Brian Anderson3d4039d2016-09-23 16:31:30 -0700650 if (CC_UNLIKELY(!mDeltas.empty())) {
651 ALOGE("FrameEventHistoryDelta: Clobbering history.");
652 }
653 mDeltas = std::move(src.mDeltas);
654 ALOGE_IF(src.mDeltas.empty(), "Source mDeltas not empty.");
655 return *this;
656}
657
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800658constexpr size_t FrameEventHistoryDelta::minFlattenedSize() {
659 return sizeof(uint32_t) + // mDeltas.size()
660 sizeof(mCompositorTiming);
Brian Anderson3890c392016-07-25 12:48:08 -0700661}
662
663size_t FrameEventHistoryDelta::getFlattenedSize() const {
664 return minFlattenedSize() +
665 std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
666 [](size_t a, const FrameEventsDelta& delta) {
667 return a + delta.getFlattenedSize();
668 });
669}
670
671size_t FrameEventHistoryDelta::getFdCount() const {
672 return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
673 [](size_t a, const FrameEventsDelta& delta) {
674 return a + delta.getFdCount();
675 });
676}
677
678status_t FrameEventHistoryDelta::flatten(
679 void*& buffer, size_t& size, int*& fds, size_t& count) const {
680 if (mDeltas.size() > FrameEventHistory::MAX_FRAME_HISTORY) {
681 return BAD_VALUE;
682 }
683 if (size < getFlattenedSize()) {
684 return NO_MEMORY;
685 }
686
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800687 FlattenableUtils::write(buffer, size, mCompositorTiming);
688
Brian Anderson3890c392016-07-25 12:48:08 -0700689 FlattenableUtils::write(
690 buffer, size, static_cast<uint32_t>(mDeltas.size()));
691 for (auto& d : mDeltas) {
692 status_t status = d.flatten(buffer, size, fds, count);
693 if (status != NO_ERROR) {
694 return status;
695 }
696 }
697 return NO_ERROR;
698}
699
700status_t FrameEventHistoryDelta::unflatten(
701 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
702 if (size < minFlattenedSize()) {
703 return NO_MEMORY;
704 }
705
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800706 FlattenableUtils::read(buffer, size, mCompositorTiming);
707
Brian Anderson3890c392016-07-25 12:48:08 -0700708 uint32_t deltaCount = 0;
709 FlattenableUtils::read(buffer, size, deltaCount);
710 if (deltaCount > FrameEventHistory::MAX_FRAME_HISTORY) {
711 return BAD_VALUE;
712 }
713 mDeltas.resize(deltaCount);
714 for (auto& d : mDeltas) {
715 status_t status = d.unflatten(buffer, size, fds, count);
716 if (status != NO_ERROR) {
717 return status;
718 }
719 }
720 return NO_ERROR;
721}
722
723
Brian Andersond6927fb2016-07-23 23:37:30 -0700724} // namespace android