blob: 019a11e2b3940e83cbc7579a773fe141669bbeff [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 Anderson8cc8b102016-10-21 12:43:09 -070019#define LOG_TAG "FrameEvents"
20
Brian Anderson3d4039d2016-09-23 16:31:30 -070021#include <cutils/compiler.h> // For CC_[UN]LIKELY
Brian Andersond6927fb2016-07-23 23:37:30 -070022#include <inttypes.h>
Brian Anderson175a7202016-10-10 16:52:56 -070023#include <utils/Log.h>
Brian Andersond6927fb2016-07-23 23:37:30 -070024#include <utils/String8.h>
25
26#include <algorithm>
27#include <limits>
Brian Anderson3890c392016-07-25 12:48:08 -070028#include <numeric>
Brian Andersond6927fb2016-07-23 23:37:30 -070029
30namespace android {
31
Brian Andersond6927fb2016-07-23 23:37:30 -070032
33// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -070034// FrameEvents
35// ============================================================================
36
Brian Anderson3890c392016-07-25 12:48:08 -070037bool FrameEvents::hasPostedInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070038 return FrameEvents::isValidTimestamp(postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -070039}
40
41bool FrameEvents::hasRequestedPresentInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070042 return FrameEvents::isValidTimestamp(requestedPresentTime);
Brian Anderson3890c392016-07-25 12:48:08 -070043}
44
45bool FrameEvents::hasLatchInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070046 return FrameEvents::isValidTimestamp(latchTime);
Brian Anderson3890c392016-07-25 12:48:08 -070047}
48
49bool FrameEvents::hasFirstRefreshStartInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070050 return FrameEvents::isValidTimestamp(firstRefreshStartTime);
Brian Anderson3890c392016-07-25 12:48:08 -070051}
52
53bool FrameEvents::hasLastRefreshStartInfo() const {
54 // The last refresh start time may continue to update until a new frame
55 // is latched. We know we have the final value once the release or retire
56 // info is set. See ConsumerFrameEventHistory::addRetire/Release.
57 return addRetireCalled || addReleaseCalled;
58}
59
Brian Andersonf6386862016-10-31 16:34:13 -070060bool FrameEvents::hasDequeueReadyInfo() const {
Brian Andersoned816e62016-10-26 16:12:21 -070061 return FrameEvents::isValidTimestamp(dequeueReadyTime);
Brian Andersonf6386862016-10-31 16:34:13 -070062}
63
Brian Anderson3890c392016-07-25 12:48:08 -070064bool FrameEvents::hasAcquireInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070065 return acquireFence->isValid();
Brian Anderson3890c392016-07-25 12:48:08 -070066}
67
68bool FrameEvents::hasGpuCompositionDoneInfo() const {
69 // We may not get a gpuCompositionDone in addPostComposite if
70 // client/gles compositing isn't needed.
71 return addPostCompositeCalled;
72}
73
74bool FrameEvents::hasDisplayPresentInfo() const {
75 // We may not get a displayPresent in addPostComposite for HWC1.
76 return addPostCompositeCalled;
77}
78
79bool FrameEvents::hasDisplayRetireInfo() const {
80 // We may not get a displayRetire in addRetire for HWC2.
81 return addRetireCalled;
82}
83
84bool FrameEvents::hasReleaseInfo() const {
85 return addReleaseCalled;
86}
87
Brian Anderson3d4039d2016-09-23 16:31:30 -070088void FrameEvents::checkFencesForCompletion() {
89 acquireFence->getSignalTime();
90 gpuCompositionDoneFence->getSignalTime();
91 displayPresentFence->getSignalTime();
92 displayRetireFence->getSignalTime();
93 releaseFence->getSignalTime();
Brian Andersond6927fb2016-07-23 23:37:30 -070094}
95
Brian Anderson3d4039d2016-09-23 16:31:30 -070096static void dumpFenceTime(String8& outString, const char* name,
97 bool pending, const FenceTime& fenceTime) {
98 outString.appendFormat("--- %s", name);
99 nsecs_t signalTime = fenceTime.getCachedSignalTime();
100 if (Fence::isValidTimestamp(signalTime)) {
101 outString.appendFormat("%" PRId64 "\n", signalTime);
102 } else if (pending || signalTime == Fence::SIGNAL_TIME_PENDING) {
103 outString.appendFormat("Pending\n");
104 } else if (&fenceTime == FenceTime::NO_FENCE.get()){
105 outString.appendFormat("N/A\n");
106 } else {
107 outString.appendFormat("Error\n");
108 }
Brian Andersond6927fb2016-07-23 23:37:30 -0700109}
110
111void FrameEvents::dump(String8& outString) const
112{
113 if (!valid) {
114 return;
115 }
116
117 outString.appendFormat("-- Frame %" PRIu64 "\n", frameNumber);
118 outString.appendFormat("--- Posted \t%" PRId64 "\n", postedTime);
119 outString.appendFormat("--- Req. Present\t%" PRId64 "\n", requestedPresentTime);
120
121 outString.appendFormat("--- Latched \t");
Brian Andersoned816e62016-10-26 16:12:21 -0700122 if (FrameEvents::isValidTimestamp(latchTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700123 outString.appendFormat("%" PRId64 "\n", latchTime);
124 } else {
125 outString.appendFormat("Pending\n");
126 }
127
128 outString.appendFormat("--- Refresh (First)\t");
Brian Andersoned816e62016-10-26 16:12:21 -0700129 if (FrameEvents::isValidTimestamp(firstRefreshStartTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700130 outString.appendFormat("%" PRId64 "\n", firstRefreshStartTime);
131 } else {
132 outString.appendFormat("Pending\n");
133 }
134
135 outString.appendFormat("--- Refresh (Last)\t");
Brian Andersoned816e62016-10-26 16:12:21 -0700136 if (FrameEvents::isValidTimestamp(lastRefreshStartTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700137 outString.appendFormat("%" PRId64 "\n", lastRefreshStartTime);
138 } else {
139 outString.appendFormat("Pending\n");
140 }
141
Brian Anderson3d4039d2016-09-23 16:31:30 -0700142 dumpFenceTime(outString, "Acquire \t",
143 true, *acquireFence);
144 dumpFenceTime(outString, "GPU Composite Done\t",
145 !addPostCompositeCalled, *gpuCompositionDoneFence);
146 dumpFenceTime(outString, "Display Present \t",
147 !addPostCompositeCalled, *displayPresentFence);
148 dumpFenceTime(outString, "Display Retire \t",
149 !addRetireCalled, *displayRetireFence);
Brian Andersonf6386862016-10-31 16:34:13 -0700150
151 outString.appendFormat("--- DequeueReady \t");
Brian Andersoned816e62016-10-26 16:12:21 -0700152 if (FrameEvents::isValidTimestamp(dequeueReadyTime)) {
Brian Andersonf6386862016-10-31 16:34:13 -0700153 outString.appendFormat("%" PRId64 "\n", dequeueReadyTime);
154 } else {
155 outString.appendFormat("Pending\n");
156 }
157
Brian Anderson3d4039d2016-09-23 16:31:30 -0700158 dumpFenceTime(outString, "Release \t",
159 true, *releaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700160}
161
162
163// ============================================================================
164// FrameEventHistory
165// ============================================================================
166
167namespace {
168
169struct FrameNumberEqual {
170 FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
171 bool operator()(const FrameEvents& frame) {
172 return frame.valid && mFrameNumber == frame.frameNumber;
173 }
174 const uint64_t mFrameNumber;
175};
176
177} // namespace
178
Brian Anderson3890c392016-07-25 12:48:08 -0700179FrameEventHistory::~FrameEventHistory() = default;
Brian Andersond6927fb2016-07-23 23:37:30 -0700180
181FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber) {
182 auto frame = std::find_if(
183 mFrames.begin(), mFrames.end(), FrameNumberEqual(frameNumber));
184 return frame == mFrames.end() ? nullptr : &(*frame);
185}
186
187FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber, size_t* iHint) {
188 *iHint = std::min(*iHint, mFrames.size());
189 auto hint = mFrames.begin() + *iHint;
190 auto frame = std::find_if(
191 hint, mFrames.end(), FrameNumberEqual(frameNumber));
192 if (frame == mFrames.end()) {
193 frame = std::find_if(
194 mFrames.begin(), hint, FrameNumberEqual(frameNumber));
195 if (frame == hint) {
196 return nullptr;
197 }
198 }
199 *iHint = static_cast<size_t>(std::distance(mFrames.begin(), frame));
200 return &(*frame);
201}
202
203void FrameEventHistory::checkFencesForCompletion() {
204 for (auto& frame : mFrames) {
205 frame.checkFencesForCompletion();
206 }
207}
208
209// Uses !|valid| as the MSB.
210static bool FrameNumberLessThan(
211 const FrameEvents& lhs, const FrameEvents& rhs) {
212 if (lhs.valid == rhs.valid) {
213 return lhs.frameNumber < rhs.frameNumber;
214 }
215 return lhs.valid;
216}
217
218void FrameEventHistory::dump(String8& outString) const {
219 auto earliestFrame = std::min_element(
220 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
221 if (!earliestFrame->valid) {
222 outString.appendFormat("-- N/A\n");
223 return;
224 }
225 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
226 frame->dump(outString);
227 }
228 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
229 frame->dump(outString);
230 }
231}
232
Brian Andersond6927fb2016-07-23 23:37:30 -0700233
Brian Anderson3890c392016-07-25 12:48:08 -0700234// ============================================================================
235// ProducerFrameEventHistory
236// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -0700237
Brian Anderson3890c392016-07-25 12:48:08 -0700238ProducerFrameEventHistory::~ProducerFrameEventHistory() = default;
239
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800240nsecs_t ProducerFrameEventHistory::snapToNextTick(
241 nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval) {
242 nsecs_t tickOffset = (tickPhase - timestamp) % tickInterval;
243 // Integer modulo rounds towards 0 and not -inf before taking the remainder,
244 // so adjust the offset if it is negative.
245 if (tickOffset < 0) {
246 tickOffset += tickInterval;
247 }
248 return timestamp + tickOffset;
249}
250
251nsecs_t ProducerFrameEventHistory::getNextCompositeDeadline(
252 const nsecs_t now) const{
253 return snapToNextTick(
254 now, mCompositorTiming.deadline, mCompositorTiming.interval);
255}
256
Brian Anderson3890c392016-07-25 12:48:08 -0700257void ProducerFrameEventHistory::updateAcquireFence(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700258 uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) {
Brian Anderson3890c392016-07-25 12:48:08 -0700259 FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
Brian Andersond6927fb2016-07-23 23:37:30 -0700260 if (frame == nullptr) {
Brian Anderson8cc8b102016-10-21 12:43:09 -0700261 ALOGE("updateAcquireFence: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700262 return;
263 }
264
Brian Anderson3890c392016-07-25 12:48:08 -0700265 if (acquire->isValid()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700266 mAcquireTimeline.push(acquire);
267 frame->acquireFence = std::move(acquire);
Brian Anderson3890c392016-07-25 12:48:08 -0700268 } else {
269 // If there isn't an acquire fence, assume that buffer was
270 // ready for the consumer when posted.
Brian Anderson3d4039d2016-09-23 16:31:30 -0700271 frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700272 }
273}
274
Brian Anderson3890c392016-07-25 12:48:08 -0700275void ProducerFrameEventHistory::applyDelta(
276 const FrameEventHistoryDelta& delta) {
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800277 mCompositorTiming = delta.mCompositorTiming;
278
Brian Anderson3890c392016-07-25 12:48:08 -0700279 for (auto& d : delta.mDeltas) {
280 // Avoid out-of-bounds access.
Brian Anderson8cc8b102016-10-21 12:43:09 -0700281 if (CC_UNLIKELY(d.mIndex >= mFrames.size())) {
282 ALOGE("applyDelta: Bad index.");
Brian Anderson3890c392016-07-25 12:48:08 -0700283 return;
284 }
285
286 FrameEvents& frame = mFrames[d.mIndex];
287
288 frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
289 frame.addRetireCalled = d.mAddRetireCalled != 0;
290 frame.addReleaseCalled = d.mAddReleaseCalled != 0;
291
292 frame.postedTime = d.mPostedTime;
293 frame.requestedPresentTime = d.mRequestedPresentTime;
294 frame.latchTime = d.mLatchTime;
295 frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
296 frame.lastRefreshStartTime = d.mLastRefreshStartTime;
Brian Andersonf6386862016-10-31 16:34:13 -0700297 frame.dequeueReadyTime = d.mDequeueReadyTime;
Brian Anderson3890c392016-07-25 12:48:08 -0700298
Brian Anderson3d4039d2016-09-23 16:31:30 -0700299 if (frame.frameNumber != d.mFrameNumber) {
300 // We got a new frame. Initialize some of the fields.
Brian Anderson3890c392016-07-25 12:48:08 -0700301 frame.frameNumber = d.mFrameNumber;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700302 frame.acquireFence = FenceTime::NO_FENCE;
303 frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
304 frame.displayPresentFence = FenceTime::NO_FENCE;
305 frame.displayRetireFence = FenceTime::NO_FENCE;
306 frame.releaseFence = FenceTime::NO_FENCE;
Brian Anderson3890c392016-07-25 12:48:08 -0700307 // The consumer only sends valid frames.
308 frame.valid = true;
Brian Andersond6927fb2016-07-23 23:37:30 -0700309 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700310
311 applyFenceDelta(&mGpuCompositionDoneTimeline,
312 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
313 applyFenceDelta(&mPresentTimeline,
314 &frame.displayPresentFence, d.mDisplayPresentFence);
315 applyFenceDelta(&mRetireTimeline,
316 &frame.displayRetireFence, d.mDisplayRetireFence);
317 applyFenceDelta(&mReleaseTimeline,
318 &frame.releaseFence, d.mReleaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700319 }
320}
321
Brian Anderson3d4039d2016-09-23 16:31:30 -0700322void ProducerFrameEventHistory::updateSignalTimes() {
323 mAcquireTimeline.updateSignalTimes();
324 mGpuCompositionDoneTimeline.updateSignalTimes();
325 mPresentTimeline.updateSignalTimes();
326 mRetireTimeline.updateSignalTimes();
327 mReleaseTimeline.updateSignalTimes();
328}
329
Brian Anderson3da8d272016-07-28 16:20:47 -0700330void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
331 std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800332 if (CC_UNLIKELY(dst == nullptr || dst->get() == nullptr)) {
Brian Anderson3da8d272016-07-28 16:20:47 -0700333 ALOGE("applyFenceDelta: dst is null.");
334 return;
335 }
336
337 switch (src.state) {
338 case FenceTime::Snapshot::State::EMPTY:
339 return;
340 case FenceTime::Snapshot::State::FENCE:
Brian Anderson8cc8b102016-10-21 12:43:09 -0700341 ALOGE_IF((*dst)->isValid(), "applyFenceDelta: Unexpected fence.");
Brian Anderson3da8d272016-07-28 16:20:47 -0700342 *dst = createFenceTime(src.fence);
343 timeline->push(*dst);
344 return;
345 case FenceTime::Snapshot::State::SIGNAL_TIME:
346 if ((*dst)->isValid()) {
347 (*dst)->applyTrustedSnapshot(src);
348 } else {
349 *dst = std::make_shared<FenceTime>(src.signalTime);
350 }
351 return;
352 }
353}
354
355std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
356 const sp<Fence>& fence) const {
357 return std::make_shared<FenceTime>(fence);
358}
359
Brian Anderson3890c392016-07-25 12:48:08 -0700360
361// ============================================================================
362// ConsumerFrameEventHistory
363// ============================================================================
364
365ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
366
Brian Anderson5ea5e592016-12-01 16:54:33 -0800367void ConsumerFrameEventHistory::onDisconnect() {
368 mCurrentConnectId++;
369 mProducerWantsEvents = false;
370}
371
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800372void ConsumerFrameEventHistory::initializeCompositorTiming(
373 const CompositorTiming& compositorTiming) {
374 mCompositorTiming = compositorTiming;
375}
376
Brian Anderson3890c392016-07-25 12:48:08 -0700377void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
378 // Overwrite all fields of the frame with default values unless set here.
379 FrameEvents newTimestamps;
Brian Anderson5ea5e592016-12-01 16:54:33 -0800380 newTimestamps.connectId = mCurrentConnectId;
Brian Anderson3890c392016-07-25 12:48:08 -0700381 newTimestamps.frameNumber = newEntry.frameNumber;
382 newTimestamps.postedTime = newEntry.postedTime;
383 newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
384 newTimestamps.acquireFence = newEntry.acquireFence;
385 newTimestamps.valid = true;
386 mFrames[mQueueOffset] = newTimestamps;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700387
388 // Note: We avoid sending the acquire fence back to the caller since
389 // they have the original one already, so there is no need to set the
390 // acquire dirty bit.
Brian Anderson3890c392016-07-25 12:48:08 -0700391 mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
Brian Anderson3890c392016-07-25 12:48:08 -0700392
393 mQueueOffset = (mQueueOffset + 1) % mFrames.size();
394}
395
396void ConsumerFrameEventHistory::addLatch(
397 uint64_t frameNumber, nsecs_t latchTime) {
398 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
399 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800400 ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700401 return;
402 }
403 frame->latchTime = latchTime;
404 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
405}
406
407void ConsumerFrameEventHistory::addPreComposition(
408 uint64_t frameNumber, nsecs_t refreshStartTime) {
409 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
410 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800411 ALOGE_IF(mProducerWantsEvents,
412 "addPreComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700413 return;
414 }
415 frame->lastRefreshStartTime = refreshStartTime;
416 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
Brian Andersoned816e62016-10-26 16:12:21 -0700417 if (!FrameEvents::isValidTimestamp(frame->firstRefreshStartTime)) {
Brian Anderson3890c392016-07-25 12:48:08 -0700418 frame->firstRefreshStartTime = refreshStartTime;
419 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
420 }
421}
422
423void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
Brian Anderson3d4039d2016-09-23 16:31:30 -0700424 const std::shared_ptr<FenceTime>& gpuCompositionDone,
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800425 const std::shared_ptr<FenceTime>& displayPresent,
426 const CompositorTiming& compositorTiming) {
427 mCompositorTiming = compositorTiming;
428
Brian Anderson3890c392016-07-25 12:48:08 -0700429 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
430 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800431 ALOGE_IF(mProducerWantsEvents,
432 "addPostComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700433 return;
434 }
435 // Only get GPU and present info for the first composite.
436 if (!frame->addPostCompositeCalled) {
437 frame->addPostCompositeCalled = true;
438 frame->gpuCompositionDoneFence = gpuCompositionDone;
Brian Andersonb04c6f02016-10-21 12:57:46 -0700439 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GPU_COMPOSITION_DONE>();
Brian Anderson3890c392016-07-25 12:48:08 -0700440 if (!frame->displayPresentFence->isValid()) {
441 frame->displayPresentFence = displayPresent;
442 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
443 }
444 }
445}
446
447void ConsumerFrameEventHistory::addRetire(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700448 uint64_t frameNumber, const std::shared_ptr<FenceTime>& displayRetire) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700449 FrameEvents* frame = getFrame(frameNumber, &mRetireOffset);
450 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800451 ALOGE_IF(mProducerWantsEvents, "addRetire: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700452 return;
453 }
454 frame->addRetireCalled = true;
455 frame->displayRetireFence = displayRetire;
Brian Anderson3890c392016-07-25 12:48:08 -0700456 mFramesDirty[mRetireOffset].setDirty<FrameEvent::DISPLAY_RETIRE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700457}
458
Brian Andersonf6386862016-10-31 16:34:13 -0700459void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber,
460 nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700461 FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
Brian Anderson5ea5e592016-12-01 16:54:33 -0800462 if (frame == nullptr) {
463 ALOGE_IF(mProducerWantsEvents, "addRelease: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700464 return;
465 }
Brian Anderson3890c392016-07-25 12:48:08 -0700466 frame->addReleaseCalled = true;
Brian Andersonf6386862016-10-31 16:34:13 -0700467 frame->dequeueReadyTime = dequeueReadyTime;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700468 frame->releaseFence = std::move(release);
Brian Anderson3890c392016-07-25 12:48:08 -0700469 mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700470}
471
Brian Anderson3d4039d2016-09-23 16:31:30 -0700472void ConsumerFrameEventHistory::getFrameDelta(
473 FrameEventHistoryDelta* delta,
474 const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800475 mProducerWantsEvents = true;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700476 size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
477 if (mFramesDirty[i].anyDirty()) {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800478 // Make sure only to send back deltas for the current connection
479 // since the producer won't have the correct state to apply a delta
480 // from a previous connection.
481 if (mFrames[i].connectId == mCurrentConnectId) {
482 delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
483 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700484 mFramesDirty[i].reset();
485 }
486}
487
Brian Anderson3890c392016-07-25 12:48:08 -0700488void ConsumerFrameEventHistory::getAndResetDelta(
489 FrameEventHistoryDelta* delta) {
Brian Anderson5ea5e592016-12-01 16:54:33 -0800490 mProducerWantsEvents = true;
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800491 delta->mCompositorTiming = mCompositorTiming;
492
Brian Anderson3d4039d2016-09-23 16:31:30 -0700493 // Write these in order of frame number so that it is easy to
494 // add them to a FenceTimeline in the proper order producer side.
Brian Anderson3890c392016-07-25 12:48:08 -0700495 delta->mDeltas.reserve(mFramesDirty.size());
Brian Anderson3d4039d2016-09-23 16:31:30 -0700496 auto earliestFrame = std::min_element(
497 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
498 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
499 getFrameDelta(delta, frame);
500 }
501 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
502 getFrameDelta(delta, frame);
Brian Anderson3890c392016-07-25 12:48:08 -0700503 }
504}
505
506
507// ============================================================================
508// FrameEventsDelta
509// ============================================================================
510
511FrameEventsDelta::FrameEventsDelta(
512 size_t index,
513 const FrameEvents& frameTimestamps,
514 const FrameEventDirtyFields& dirtyFields)
515 : mIndex(index),
516 mFrameNumber(frameTimestamps.frameNumber),
517 mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
518 mAddRetireCalled(frameTimestamps.addRetireCalled),
519 mAddReleaseCalled(frameTimestamps.addReleaseCalled),
520 mPostedTime(frameTimestamps.postedTime),
521 mRequestedPresentTime(frameTimestamps.requestedPresentTime),
522 mLatchTime(frameTimestamps.latchTime),
523 mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
Brian Andersonf6386862016-10-31 16:34:13 -0700524 mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime),
525 mDequeueReadyTime(frameTimestamps.dequeueReadyTime) {
Brian Andersonb04c6f02016-10-21 12:57:46 -0700526 if (dirtyFields.isDirty<FrameEvent::GPU_COMPOSITION_DONE>()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700527 mGpuCompositionDoneFence =
528 frameTimestamps.gpuCompositionDoneFence->getSnapshot();
529 }
530 if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
531 mDisplayPresentFence =
532 frameTimestamps.displayPresentFence->getSnapshot();
533 }
534 if (dirtyFields.isDirty<FrameEvent::DISPLAY_RETIRE>()) {
535 mDisplayRetireFence = frameTimestamps.displayRetireFence->getSnapshot();
536 }
537 if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
538 mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
539 }
Brian Anderson3890c392016-07-25 12:48:08 -0700540}
541
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800542constexpr size_t FrameEventsDelta::minFlattenedSize() {
543 return sizeof(FrameEventsDelta::mFrameNumber) +
Brian Anderson3890c392016-07-25 12:48:08 -0700544 sizeof(uint8_t) + // mIndex
545 sizeof(uint8_t) + // mAddPostCompositeCalled
546 sizeof(uint8_t) + // mAddRetireCalled
547 sizeof(uint8_t) + // mAddReleaseCalled
548 sizeof(FrameEventsDelta::mPostedTime) +
549 sizeof(FrameEventsDelta::mRequestedPresentTime) +
550 sizeof(FrameEventsDelta::mLatchTime) +
551 sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
Brian Andersonf6386862016-10-31 16:34:13 -0700552 sizeof(FrameEventsDelta::mLastRefreshStartTime) +
553 sizeof(FrameEventsDelta::mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700554}
555
556// Flattenable implementation
557size_t FrameEventsDelta::getFlattenedSize() const {
558 auto fences = allFences(this);
559 return minFlattenedSize() +
560 std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700561 [](size_t a, const FenceTime::Snapshot* fence) {
562 return a + fence->getFlattenedSize();
Brian Anderson3890c392016-07-25 12:48:08 -0700563 });
564}
565
566size_t FrameEventsDelta::getFdCount() const {
567 auto fences = allFences(this);
568 return std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700569 [](size_t a, const FenceTime::Snapshot* fence) {
570 return a + fence->getFdCount();
Brian Anderson3890c392016-07-25 12:48:08 -0700571 });
572}
573
574status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
575 size_t& count) const {
576 if (size < getFlattenedSize() || count < getFdCount()) {
577 return NO_MEMORY;
578 }
579
580 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY ||
581 mIndex > std::numeric_limits<uint8_t>::max()) {
582 return BAD_VALUE;
583 }
584
585 FlattenableUtils::write(buffer, size, mFrameNumber);
586
587 // These are static_cast to uint8_t for alignment.
588 FlattenableUtils::write(buffer, size, static_cast<uint8_t>(mIndex));
589 FlattenableUtils::write(
590 buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
591 FlattenableUtils::write(
592 buffer, size, static_cast<uint8_t>(mAddRetireCalled));
593 FlattenableUtils::write(
594 buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
595
596 FlattenableUtils::write(buffer, size, mPostedTime);
597 FlattenableUtils::write(buffer, size, mRequestedPresentTime);
598 FlattenableUtils::write(buffer, size, mLatchTime);
599 FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
600 FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700601 FlattenableUtils::write(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700602
603 // Fences
604 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700605 status_t status = fence->flatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700606 if (status != NO_ERROR) {
607 return status;
608 }
609 }
610 return NO_ERROR;
611}
612
613status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
614 int const*& fds, size_t& count) {
615 if (size < minFlattenedSize()) {
616 return NO_MEMORY;
617 }
618
619 FlattenableUtils::read(buffer, size, mFrameNumber);
620
621 // These were written as uint8_t for alignment.
622 uint8_t temp = 0;
623 FlattenableUtils::read(buffer, size, temp);
624 mIndex = temp;
625 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY) {
626 return BAD_VALUE;
627 }
628 FlattenableUtils::read(buffer, size, temp);
629 mAddPostCompositeCalled = static_cast<bool>(temp);
630 FlattenableUtils::read(buffer, size, temp);
631 mAddRetireCalled = static_cast<bool>(temp);
632 FlattenableUtils::read(buffer, size, temp);
633 mAddReleaseCalled = static_cast<bool>(temp);
634
635 FlattenableUtils::read(buffer, size, mPostedTime);
636 FlattenableUtils::read(buffer, size, mRequestedPresentTime);
637 FlattenableUtils::read(buffer, size, mLatchTime);
638 FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
639 FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
Brian Andersonf6386862016-10-31 16:34:13 -0700640 FlattenableUtils::read(buffer, size, mDequeueReadyTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700641
642 // Fences
643 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700644 status_t status = fence->unflatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700645 if (status != NO_ERROR) {
646 return status;
647 }
648 }
649 return NO_ERROR;
650}
651
652
653// ============================================================================
654// FrameEventHistoryDelta
655// ============================================================================
656
Brian Anderson3d4039d2016-09-23 16:31:30 -0700657FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
658 FrameEventHistoryDelta&& src) {
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800659 mCompositorTiming = src.mCompositorTiming;
660
Brian Anderson3d4039d2016-09-23 16:31:30 -0700661 if (CC_UNLIKELY(!mDeltas.empty())) {
Brian Anderson8cc8b102016-10-21 12:43:09 -0700662 ALOGE("FrameEventHistoryDelta assign clobbering history.");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700663 }
664 mDeltas = std::move(src.mDeltas);
665 ALOGE_IF(src.mDeltas.empty(), "Source mDeltas not empty.");
666 return *this;
667}
668
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800669constexpr size_t FrameEventHistoryDelta::minFlattenedSize() {
670 return sizeof(uint32_t) + // mDeltas.size()
671 sizeof(mCompositorTiming);
Brian Anderson3890c392016-07-25 12:48:08 -0700672}
673
674size_t FrameEventHistoryDelta::getFlattenedSize() const {
675 return minFlattenedSize() +
676 std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
677 [](size_t a, const FrameEventsDelta& delta) {
678 return a + delta.getFlattenedSize();
679 });
680}
681
682size_t FrameEventHistoryDelta::getFdCount() const {
683 return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
684 [](size_t a, const FrameEventsDelta& delta) {
685 return a + delta.getFdCount();
686 });
687}
688
689status_t FrameEventHistoryDelta::flatten(
690 void*& buffer, size_t& size, int*& fds, size_t& count) const {
691 if (mDeltas.size() > FrameEventHistory::MAX_FRAME_HISTORY) {
692 return BAD_VALUE;
693 }
694 if (size < getFlattenedSize()) {
695 return NO_MEMORY;
696 }
697
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800698 FlattenableUtils::write(buffer, size, mCompositorTiming);
699
Brian Anderson3890c392016-07-25 12:48:08 -0700700 FlattenableUtils::write(
701 buffer, size, static_cast<uint32_t>(mDeltas.size()));
702 for (auto& d : mDeltas) {
703 status_t status = d.flatten(buffer, size, fds, count);
704 if (status != NO_ERROR) {
705 return status;
706 }
707 }
708 return NO_ERROR;
709}
710
711status_t FrameEventHistoryDelta::unflatten(
712 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
713 if (size < minFlattenedSize()) {
714 return NO_MEMORY;
715 }
716
Brian Anderson0a61b0c2016-12-07 14:55:56 -0800717 FlattenableUtils::read(buffer, size, mCompositorTiming);
718
Brian Anderson3890c392016-07-25 12:48:08 -0700719 uint32_t deltaCount = 0;
720 FlattenableUtils::read(buffer, size, deltaCount);
721 if (deltaCount > FrameEventHistory::MAX_FRAME_HISTORY) {
722 return BAD_VALUE;
723 }
724 mDeltas.resize(deltaCount);
725 for (auto& d : mDeltas) {
726 status_t status = d.unflatten(buffer, size, fds, count);
727 if (status != NO_ERROR) {
728 return status;
729 }
730 }
731 return NO_ERROR;
732}
733
734
Brian Andersond6927fb2016-07-23 23:37:30 -0700735} // namespace android