blob: fb242f79fdbe04836eb00ce02f9e43f055617489 [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
58bool FrameEvents::hasAcquireInfo() const {
Brian Anderson3d4039d2016-09-23 16:31:30 -070059 return acquireFence->isValid();
Brian Anderson3890c392016-07-25 12:48:08 -070060}
61
62bool FrameEvents::hasGpuCompositionDoneInfo() const {
63 // We may not get a gpuCompositionDone in addPostComposite if
64 // client/gles compositing isn't needed.
65 return addPostCompositeCalled;
66}
67
68bool FrameEvents::hasDisplayPresentInfo() const {
69 // We may not get a displayPresent in addPostComposite for HWC1.
70 return addPostCompositeCalled;
71}
72
73bool FrameEvents::hasDisplayRetireInfo() const {
74 // We may not get a displayRetire in addRetire for HWC2.
75 return addRetireCalled;
76}
77
78bool FrameEvents::hasReleaseInfo() const {
79 return addReleaseCalled;
80}
81
Brian Anderson3d4039d2016-09-23 16:31:30 -070082void FrameEvents::checkFencesForCompletion() {
83 acquireFence->getSignalTime();
84 gpuCompositionDoneFence->getSignalTime();
85 displayPresentFence->getSignalTime();
86 displayRetireFence->getSignalTime();
87 releaseFence->getSignalTime();
Brian Andersond6927fb2016-07-23 23:37:30 -070088}
89
Brian Anderson3d4039d2016-09-23 16:31:30 -070090static void dumpFenceTime(String8& outString, const char* name,
91 bool pending, const FenceTime& fenceTime) {
92 outString.appendFormat("--- %s", name);
93 nsecs_t signalTime = fenceTime.getCachedSignalTime();
94 if (Fence::isValidTimestamp(signalTime)) {
95 outString.appendFormat("%" PRId64 "\n", signalTime);
96 } else if (pending || signalTime == Fence::SIGNAL_TIME_PENDING) {
97 outString.appendFormat("Pending\n");
98 } else if (&fenceTime == FenceTime::NO_FENCE.get()){
99 outString.appendFormat("N/A\n");
100 } else {
101 outString.appendFormat("Error\n");
102 }
Brian Andersond6927fb2016-07-23 23:37:30 -0700103}
104
105void FrameEvents::dump(String8& outString) const
106{
107 if (!valid) {
108 return;
109 }
110
111 outString.appendFormat("-- Frame %" PRIu64 "\n", frameNumber);
112 outString.appendFormat("--- Posted \t%" PRId64 "\n", postedTime);
113 outString.appendFormat("--- Req. Present\t%" PRId64 "\n", requestedPresentTime);
114
115 outString.appendFormat("--- Latched \t");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700116 if (Fence::isValidTimestamp(latchTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700117 outString.appendFormat("%" PRId64 "\n", latchTime);
118 } else {
119 outString.appendFormat("Pending\n");
120 }
121
122 outString.appendFormat("--- Refresh (First)\t");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700123 if (Fence::isValidTimestamp(firstRefreshStartTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700124 outString.appendFormat("%" PRId64 "\n", firstRefreshStartTime);
125 } else {
126 outString.appendFormat("Pending\n");
127 }
128
129 outString.appendFormat("--- Refresh (Last)\t");
Brian Anderson3d4039d2016-09-23 16:31:30 -0700130 if (Fence::isValidTimestamp(lastRefreshStartTime)) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700131 outString.appendFormat("%" PRId64 "\n", lastRefreshStartTime);
132 } else {
133 outString.appendFormat("Pending\n");
134 }
135
Brian Anderson3d4039d2016-09-23 16:31:30 -0700136 dumpFenceTime(outString, "Acquire \t",
137 true, *acquireFence);
138 dumpFenceTime(outString, "GPU Composite Done\t",
139 !addPostCompositeCalled, *gpuCompositionDoneFence);
140 dumpFenceTime(outString, "Display Present \t",
141 !addPostCompositeCalled, *displayPresentFence);
142 dumpFenceTime(outString, "Display Retire \t",
143 !addRetireCalled, *displayRetireFence);
144 dumpFenceTime(outString, "Release \t",
145 true, *releaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700146}
147
148
149// ============================================================================
150// FrameEventHistory
151// ============================================================================
152
153namespace {
154
155struct FrameNumberEqual {
156 FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
157 bool operator()(const FrameEvents& frame) {
158 return frame.valid && mFrameNumber == frame.frameNumber;
159 }
160 const uint64_t mFrameNumber;
161};
162
163} // namespace
164
Brian Anderson3890c392016-07-25 12:48:08 -0700165FrameEventHistory::~FrameEventHistory() = default;
Brian Andersond6927fb2016-07-23 23:37:30 -0700166
167FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber) {
168 auto frame = std::find_if(
169 mFrames.begin(), mFrames.end(), FrameNumberEqual(frameNumber));
170 return frame == mFrames.end() ? nullptr : &(*frame);
171}
172
173FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber, size_t* iHint) {
174 *iHint = std::min(*iHint, mFrames.size());
175 auto hint = mFrames.begin() + *iHint;
176 auto frame = std::find_if(
177 hint, mFrames.end(), FrameNumberEqual(frameNumber));
178 if (frame == mFrames.end()) {
179 frame = std::find_if(
180 mFrames.begin(), hint, FrameNumberEqual(frameNumber));
181 if (frame == hint) {
182 return nullptr;
183 }
184 }
185 *iHint = static_cast<size_t>(std::distance(mFrames.begin(), frame));
186 return &(*frame);
187}
188
189void FrameEventHistory::checkFencesForCompletion() {
190 for (auto& frame : mFrames) {
191 frame.checkFencesForCompletion();
192 }
193}
194
195// Uses !|valid| as the MSB.
196static bool FrameNumberLessThan(
197 const FrameEvents& lhs, const FrameEvents& rhs) {
198 if (lhs.valid == rhs.valid) {
199 return lhs.frameNumber < rhs.frameNumber;
200 }
201 return lhs.valid;
202}
203
204void FrameEventHistory::dump(String8& outString) const {
205 auto earliestFrame = std::min_element(
206 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
207 if (!earliestFrame->valid) {
208 outString.appendFormat("-- N/A\n");
209 return;
210 }
211 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
212 frame->dump(outString);
213 }
214 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
215 frame->dump(outString);
216 }
217}
218
Brian Andersond6927fb2016-07-23 23:37:30 -0700219
Brian Anderson3890c392016-07-25 12:48:08 -0700220// ============================================================================
221// ProducerFrameEventHistory
222// ============================================================================
Brian Andersond6927fb2016-07-23 23:37:30 -0700223
Brian Anderson3890c392016-07-25 12:48:08 -0700224ProducerFrameEventHistory::~ProducerFrameEventHistory() = default;
225
226void ProducerFrameEventHistory::updateAcquireFence(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700227 uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) {
Brian Anderson3890c392016-07-25 12:48:08 -0700228 FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
Brian Andersond6927fb2016-07-23 23:37:30 -0700229 if (frame == nullptr) {
Brian Anderson3890c392016-07-25 12:48:08 -0700230 ALOGE("ProducerFrameEventHistory::updateAcquireFence: "
231 "Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700232 return;
233 }
234
Brian Anderson3890c392016-07-25 12:48:08 -0700235 if (acquire->isValid()) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700236 mAcquireTimeline.push(acquire);
237 frame->acquireFence = std::move(acquire);
Brian Anderson3890c392016-07-25 12:48:08 -0700238 } else {
239 // If there isn't an acquire fence, assume that buffer was
240 // ready for the consumer when posted.
Brian Anderson3d4039d2016-09-23 16:31:30 -0700241 frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
Brian Anderson3890c392016-07-25 12:48:08 -0700242 }
243}
244
Brian Anderson3890c392016-07-25 12:48:08 -0700245void ProducerFrameEventHistory::applyDelta(
246 const FrameEventHistoryDelta& delta) {
247 for (auto& d : delta.mDeltas) {
248 // Avoid out-of-bounds access.
249 if (d.mIndex >= mFrames.size()) {
250 ALOGE("ProducerFrameEventHistory::applyDelta: Bad index.");
251 return;
252 }
253
254 FrameEvents& frame = mFrames[d.mIndex];
255
256 frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
257 frame.addRetireCalled = d.mAddRetireCalled != 0;
258 frame.addReleaseCalled = d.mAddReleaseCalled != 0;
259
260 frame.postedTime = d.mPostedTime;
261 frame.requestedPresentTime = d.mRequestedPresentTime;
262 frame.latchTime = d.mLatchTime;
263 frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
264 frame.lastRefreshStartTime = d.mLastRefreshStartTime;
265
Brian Anderson3d4039d2016-09-23 16:31:30 -0700266 if (frame.frameNumber != d.mFrameNumber) {
267 // We got a new frame. Initialize some of the fields.
Brian Anderson3890c392016-07-25 12:48:08 -0700268 frame.frameNumber = d.mFrameNumber;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700269 frame.acquireFence = FenceTime::NO_FENCE;
270 frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
271 frame.displayPresentFence = FenceTime::NO_FENCE;
272 frame.displayRetireFence = FenceTime::NO_FENCE;
273 frame.releaseFence = FenceTime::NO_FENCE;
Brian Anderson3890c392016-07-25 12:48:08 -0700274 // The consumer only sends valid frames.
275 frame.valid = true;
Brian Andersond6927fb2016-07-23 23:37:30 -0700276 }
Brian Anderson3d4039d2016-09-23 16:31:30 -0700277
278 applyFenceDelta(&mGpuCompositionDoneTimeline,
279 &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
280 applyFenceDelta(&mPresentTimeline,
281 &frame.displayPresentFence, d.mDisplayPresentFence);
282 applyFenceDelta(&mRetireTimeline,
283 &frame.displayRetireFence, d.mDisplayRetireFence);
284 applyFenceDelta(&mReleaseTimeline,
285 &frame.releaseFence, d.mReleaseFence);
Brian Andersond6927fb2016-07-23 23:37:30 -0700286 }
287}
288
Brian Anderson3d4039d2016-09-23 16:31:30 -0700289void ProducerFrameEventHistory::updateSignalTimes() {
290 mAcquireTimeline.updateSignalTimes();
291 mGpuCompositionDoneTimeline.updateSignalTimes();
292 mPresentTimeline.updateSignalTimes();
293 mRetireTimeline.updateSignalTimes();
294 mReleaseTimeline.updateSignalTimes();
295}
296
Brian Anderson3da8d272016-07-28 16:20:47 -0700297void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
298 std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
299 if (CC_UNLIKELY(dst == nullptr)) {
300 ALOGE("applyFenceDelta: dst is null.");
301 return;
302 }
303
304 switch (src.state) {
305 case FenceTime::Snapshot::State::EMPTY:
306 return;
307 case FenceTime::Snapshot::State::FENCE:
308 if (CC_UNLIKELY((*dst)->isValid())) {
309 ALOGE("applyFenceDelta: Unexpected fence.");
310 }
311 *dst = createFenceTime(src.fence);
312 timeline->push(*dst);
313 return;
314 case FenceTime::Snapshot::State::SIGNAL_TIME:
315 if ((*dst)->isValid()) {
316 (*dst)->applyTrustedSnapshot(src);
317 } else {
318 *dst = std::make_shared<FenceTime>(src.signalTime);
319 }
320 return;
321 }
322}
323
324std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
325 const sp<Fence>& fence) const {
326 return std::make_shared<FenceTime>(fence);
327}
328
Brian Anderson3890c392016-07-25 12:48:08 -0700329
330// ============================================================================
331// ConsumerFrameEventHistory
332// ============================================================================
333
334ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
335
336void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
337 // Overwrite all fields of the frame with default values unless set here.
338 FrameEvents newTimestamps;
339 newTimestamps.frameNumber = newEntry.frameNumber;
340 newTimestamps.postedTime = newEntry.postedTime;
341 newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
342 newTimestamps.acquireFence = newEntry.acquireFence;
343 newTimestamps.valid = true;
344 mFrames[mQueueOffset] = newTimestamps;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700345
346 // Note: We avoid sending the acquire fence back to the caller since
347 // they have the original one already, so there is no need to set the
348 // acquire dirty bit.
Brian Anderson3890c392016-07-25 12:48:08 -0700349 mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
Brian Anderson3890c392016-07-25 12:48:08 -0700350
351 mQueueOffset = (mQueueOffset + 1) % mFrames.size();
352}
353
354void ConsumerFrameEventHistory::addLatch(
355 uint64_t frameNumber, nsecs_t latchTime) {
356 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
357 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800358 ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700359 return;
360 }
361 frame->latchTime = latchTime;
362 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
363}
364
365void ConsumerFrameEventHistory::addPreComposition(
366 uint64_t frameNumber, nsecs_t refreshStartTime) {
367 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
368 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800369 ALOGE_IF(mProducerWantsEvents,
370 "addPreComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700371 return;
372 }
373 frame->lastRefreshStartTime = refreshStartTime;
374 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
Brian Anderson3d4039d2016-09-23 16:31:30 -0700375 if (!Fence::isValidTimestamp(frame->firstRefreshStartTime)) {
Brian Anderson3890c392016-07-25 12:48:08 -0700376 frame->firstRefreshStartTime = refreshStartTime;
377 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
378 }
379}
380
381void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
Brian Anderson3d4039d2016-09-23 16:31:30 -0700382 const std::shared_ptr<FenceTime>& gpuCompositionDone,
383 const std::shared_ptr<FenceTime>& displayPresent) {
Brian Anderson3890c392016-07-25 12:48:08 -0700384 FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
385 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800386 ALOGE_IF(mProducerWantsEvents,
387 "addPostComposition: Did not find frame.");
Brian Anderson3890c392016-07-25 12:48:08 -0700388 return;
389 }
390 // Only get GPU and present info for the first composite.
391 if (!frame->addPostCompositeCalled) {
392 frame->addPostCompositeCalled = true;
393 frame->gpuCompositionDoneFence = gpuCompositionDone;
394 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GL_COMPOSITION_DONE>();
395 if (!frame->displayPresentFence->isValid()) {
396 frame->displayPresentFence = displayPresent;
397 mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
398 }
399 }
400}
401
402void ConsumerFrameEventHistory::addRetire(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700403 uint64_t frameNumber, const std::shared_ptr<FenceTime>& displayRetire) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700404 FrameEvents* frame = getFrame(frameNumber, &mRetireOffset);
405 if (frame == nullptr) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800406 ALOGE_IF(mProducerWantsEvents, "addRetire: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700407 return;
408 }
409 frame->addRetireCalled = true;
410 frame->displayRetireFence = displayRetire;
Brian Anderson3890c392016-07-25 12:48:08 -0700411 mFramesDirty[mRetireOffset].setDirty<FrameEvent::DISPLAY_RETIRE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700412}
413
Brian Anderson3890c392016-07-25 12:48:08 -0700414void ConsumerFrameEventHistory::addRelease(
Brian Anderson3d4039d2016-09-23 16:31:30 -0700415 uint64_t frameNumber, std::shared_ptr<FenceTime>&& release) {
Brian Andersond6927fb2016-07-23 23:37:30 -0700416 FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
417 if (frame == nullptr) {
Brian Anderson3890c392016-07-25 12:48:08 -0700418 ALOGE("ConsumerFrameEventHistory::addRelease: Did not find frame.");
Brian Andersond6927fb2016-07-23 23:37:30 -0700419 return;
420 }
Brian Anderson3890c392016-07-25 12:48:08 -0700421 frame->addReleaseCalled = true;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700422 frame->releaseFence = std::move(release);
Brian Anderson3890c392016-07-25 12:48:08 -0700423 mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
Brian Andersond6927fb2016-07-23 23:37:30 -0700424}
425
Brian Anderson3d4039d2016-09-23 16:31:30 -0700426void ConsumerFrameEventHistory::getFrameDelta(
427 FrameEventHistoryDelta* delta,
428 const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame) {
Brian Anderson4565daa2016-12-13 15:41:28 -0800429 mProducerWantsEvents = true;
Brian Anderson3d4039d2016-09-23 16:31:30 -0700430 size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
431 if (mFramesDirty[i].anyDirty()) {
432 delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
433 mFramesDirty[i].reset();
434 }
435}
436
Brian Anderson3890c392016-07-25 12:48:08 -0700437void ConsumerFrameEventHistory::getAndResetDelta(
438 FrameEventHistoryDelta* delta) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700439 // Write these in order of frame number so that it is easy to
440 // add them to a FenceTimeline in the proper order producer side.
Brian Anderson3890c392016-07-25 12:48:08 -0700441 delta->mDeltas.reserve(mFramesDirty.size());
Brian Anderson3d4039d2016-09-23 16:31:30 -0700442 auto earliestFrame = std::min_element(
443 mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
444 for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
445 getFrameDelta(delta, frame);
446 }
447 for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
448 getFrameDelta(delta, frame);
Brian Anderson3890c392016-07-25 12:48:08 -0700449 }
450}
451
452
453// ============================================================================
454// FrameEventsDelta
455// ============================================================================
456
457FrameEventsDelta::FrameEventsDelta(
458 size_t index,
459 const FrameEvents& frameTimestamps,
460 const FrameEventDirtyFields& dirtyFields)
461 : mIndex(index),
462 mFrameNumber(frameTimestamps.frameNumber),
463 mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
464 mAddRetireCalled(frameTimestamps.addRetireCalled),
465 mAddReleaseCalled(frameTimestamps.addReleaseCalled),
466 mPostedTime(frameTimestamps.postedTime),
467 mRequestedPresentTime(frameTimestamps.requestedPresentTime),
468 mLatchTime(frameTimestamps.latchTime),
469 mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
470 mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700471 if (dirtyFields.isDirty<FrameEvent::GL_COMPOSITION_DONE>()) {
472 mGpuCompositionDoneFence =
473 frameTimestamps.gpuCompositionDoneFence->getSnapshot();
474 }
475 if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
476 mDisplayPresentFence =
477 frameTimestamps.displayPresentFence->getSnapshot();
478 }
479 if (dirtyFields.isDirty<FrameEvent::DISPLAY_RETIRE>()) {
480 mDisplayRetireFence = frameTimestamps.displayRetireFence->getSnapshot();
481 }
482 if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
483 mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
484 }
Brian Anderson3890c392016-07-25 12:48:08 -0700485}
486
487size_t FrameEventsDelta::minFlattenedSize() {
488 constexpr size_t min =
489 sizeof(FrameEventsDelta::mFrameNumber) +
490 sizeof(uint8_t) + // mIndex
491 sizeof(uint8_t) + // mAddPostCompositeCalled
492 sizeof(uint8_t) + // mAddRetireCalled
493 sizeof(uint8_t) + // mAddReleaseCalled
494 sizeof(FrameEventsDelta::mPostedTime) +
495 sizeof(FrameEventsDelta::mRequestedPresentTime) +
496 sizeof(FrameEventsDelta::mLatchTime) +
497 sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
498 sizeof(FrameEventsDelta::mLastRefreshStartTime);
499 return min;
500}
501
502// Flattenable implementation
503size_t FrameEventsDelta::getFlattenedSize() const {
504 auto fences = allFences(this);
505 return minFlattenedSize() +
506 std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700507 [](size_t a, const FenceTime::Snapshot* fence) {
508 return a + fence->getFlattenedSize();
Brian Anderson3890c392016-07-25 12:48:08 -0700509 });
510}
511
512size_t FrameEventsDelta::getFdCount() const {
513 auto fences = allFences(this);
514 return std::accumulate(fences.begin(), fences.end(), size_t(0),
Brian Anderson3d4039d2016-09-23 16:31:30 -0700515 [](size_t a, const FenceTime::Snapshot* fence) {
516 return a + fence->getFdCount();
Brian Anderson3890c392016-07-25 12:48:08 -0700517 });
518}
519
520status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
521 size_t& count) const {
522 if (size < getFlattenedSize() || count < getFdCount()) {
523 return NO_MEMORY;
524 }
525
526 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY ||
527 mIndex > std::numeric_limits<uint8_t>::max()) {
528 return BAD_VALUE;
529 }
530
531 FlattenableUtils::write(buffer, size, mFrameNumber);
532
533 // These are static_cast to uint8_t for alignment.
534 FlattenableUtils::write(buffer, size, static_cast<uint8_t>(mIndex));
535 FlattenableUtils::write(
536 buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
537 FlattenableUtils::write(
538 buffer, size, static_cast<uint8_t>(mAddRetireCalled));
539 FlattenableUtils::write(
540 buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
541
542 FlattenableUtils::write(buffer, size, mPostedTime);
543 FlattenableUtils::write(buffer, size, mRequestedPresentTime);
544 FlattenableUtils::write(buffer, size, mLatchTime);
545 FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
546 FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
547
548 // Fences
549 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700550 status_t status = fence->flatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700551 if (status != NO_ERROR) {
552 return status;
553 }
554 }
555 return NO_ERROR;
556}
557
558status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
559 int const*& fds, size_t& count) {
560 if (size < minFlattenedSize()) {
561 return NO_MEMORY;
562 }
563
564 FlattenableUtils::read(buffer, size, mFrameNumber);
565
566 // These were written as uint8_t for alignment.
567 uint8_t temp = 0;
568 FlattenableUtils::read(buffer, size, temp);
569 mIndex = temp;
570 if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY) {
571 return BAD_VALUE;
572 }
573 FlattenableUtils::read(buffer, size, temp);
574 mAddPostCompositeCalled = static_cast<bool>(temp);
575 FlattenableUtils::read(buffer, size, temp);
576 mAddRetireCalled = static_cast<bool>(temp);
577 FlattenableUtils::read(buffer, size, temp);
578 mAddReleaseCalled = static_cast<bool>(temp);
579
580 FlattenableUtils::read(buffer, size, mPostedTime);
581 FlattenableUtils::read(buffer, size, mRequestedPresentTime);
582 FlattenableUtils::read(buffer, size, mLatchTime);
583 FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
584 FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
585
586 // Fences
587 for (auto fence : allFences(this)) {
Brian Anderson3d4039d2016-09-23 16:31:30 -0700588 status_t status = fence->unflatten(buffer, size, fds, count);
Brian Anderson3890c392016-07-25 12:48:08 -0700589 if (status != NO_ERROR) {
590 return status;
591 }
592 }
593 return NO_ERROR;
594}
595
596
597// ============================================================================
598// FrameEventHistoryDelta
599// ============================================================================
600
Brian Anderson3d4039d2016-09-23 16:31:30 -0700601FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
602 FrameEventHistoryDelta&& src) {
603 if (CC_UNLIKELY(!mDeltas.empty())) {
604 ALOGE("FrameEventHistoryDelta: Clobbering history.");
605 }
606 mDeltas = std::move(src.mDeltas);
607 ALOGE_IF(src.mDeltas.empty(), "Source mDeltas not empty.");
608 return *this;
609}
610
Brian Anderson3890c392016-07-25 12:48:08 -0700611size_t FrameEventHistoryDelta::minFlattenedSize() {
612 return sizeof(uint32_t);
613}
614
615size_t FrameEventHistoryDelta::getFlattenedSize() const {
616 return minFlattenedSize() +
617 std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
618 [](size_t a, const FrameEventsDelta& delta) {
619 return a + delta.getFlattenedSize();
620 });
621}
622
623size_t FrameEventHistoryDelta::getFdCount() const {
624 return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
625 [](size_t a, const FrameEventsDelta& delta) {
626 return a + delta.getFdCount();
627 });
628}
629
630status_t FrameEventHistoryDelta::flatten(
631 void*& buffer, size_t& size, int*& fds, size_t& count) const {
632 if (mDeltas.size() > FrameEventHistory::MAX_FRAME_HISTORY) {
633 return BAD_VALUE;
634 }
635 if (size < getFlattenedSize()) {
636 return NO_MEMORY;
637 }
638
639 FlattenableUtils::write(
640 buffer, size, static_cast<uint32_t>(mDeltas.size()));
641 for (auto& d : mDeltas) {
642 status_t status = d.flatten(buffer, size, fds, count);
643 if (status != NO_ERROR) {
644 return status;
645 }
646 }
647 return NO_ERROR;
648}
649
650status_t FrameEventHistoryDelta::unflatten(
651 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
652 if (size < minFlattenedSize()) {
653 return NO_MEMORY;
654 }
655
656 uint32_t deltaCount = 0;
657 FlattenableUtils::read(buffer, size, deltaCount);
658 if (deltaCount > FrameEventHistory::MAX_FRAME_HISTORY) {
659 return BAD_VALUE;
660 }
661 mDeltas.resize(deltaCount);
662 for (auto& d : mDeltas) {
663 status_t status = d.unflatten(buffer, size, fds, count);
664 if (status != NO_ERROR) {
665 return status;
666 }
667 }
668 return NO_ERROR;
669}
670
671
Brian Andersond6927fb2016-07-23 23:37:30 -0700672} // namespace android