FrameTimestamps.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. /*
  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. #include <gui/FrameTimestamps.h>
  17. #define LOG_TAG "FrameEvents"
  18. #include <android-base/stringprintf.h>
  19. #include <cutils/compiler.h> // For CC_[UN]LIKELY
  20. #include <inttypes.h>
  21. #include <utils/Log.h>
  22. #include <algorithm>
  23. #include <limits>
  24. #include <numeric>
  25. namespace android {
  26. using base::StringAppendF;
  27. // ============================================================================
  28. // FrameEvents
  29. // ============================================================================
  30. bool FrameEvents::hasPostedInfo() const {
  31. return FrameEvents::isValidTimestamp(postedTime);
  32. }
  33. bool FrameEvents::hasRequestedPresentInfo() const {
  34. return FrameEvents::isValidTimestamp(requestedPresentTime);
  35. }
  36. bool FrameEvents::hasLatchInfo() const {
  37. return FrameEvents::isValidTimestamp(latchTime);
  38. }
  39. bool FrameEvents::hasFirstRefreshStartInfo() const {
  40. return FrameEvents::isValidTimestamp(firstRefreshStartTime);
  41. }
  42. bool FrameEvents::hasLastRefreshStartInfo() const {
  43. // The last refresh start time may continue to update until a new frame
  44. // is latched. We know we have the final value once the release info is set.
  45. return addReleaseCalled;
  46. }
  47. bool FrameEvents::hasDequeueReadyInfo() const {
  48. return FrameEvents::isValidTimestamp(dequeueReadyTime);
  49. }
  50. bool FrameEvents::hasAcquireInfo() const {
  51. return acquireFence->isValid();
  52. }
  53. bool FrameEvents::hasGpuCompositionDoneInfo() const {
  54. // We may not get a gpuCompositionDone in addPostComposite if
  55. // client/gles compositing isn't needed.
  56. return addPostCompositeCalled;
  57. }
  58. bool FrameEvents::hasDisplayPresentInfo() const {
  59. // We may not get a displayPresent in addPostComposite for HWC1.
  60. return addPostCompositeCalled;
  61. }
  62. bool FrameEvents::hasReleaseInfo() const {
  63. return addReleaseCalled;
  64. }
  65. void FrameEvents::checkFencesForCompletion() {
  66. acquireFence->getSignalTime();
  67. gpuCompositionDoneFence->getSignalTime();
  68. displayPresentFence->getSignalTime();
  69. releaseFence->getSignalTime();
  70. }
  71. static void dumpFenceTime(std::string& outString, const char* name, bool pending,
  72. const FenceTime& fenceTime) {
  73. StringAppendF(&outString, "--- %s", name);
  74. nsecs_t signalTime = fenceTime.getCachedSignalTime();
  75. if (Fence::isValidTimestamp(signalTime)) {
  76. StringAppendF(&outString, "%" PRId64 "\n", signalTime);
  77. } else if (pending || signalTime == Fence::SIGNAL_TIME_PENDING) {
  78. outString.append("Pending\n");
  79. } else if (&fenceTime == FenceTime::NO_FENCE.get()){
  80. outString.append("N/A\n");
  81. } else {
  82. outString.append("Error\n");
  83. }
  84. }
  85. void FrameEvents::dump(std::string& outString) const {
  86. if (!valid) {
  87. return;
  88. }
  89. StringAppendF(&outString, "-- Frame %" PRIu64 "\n", frameNumber);
  90. StringAppendF(&outString, "--- Posted \t%" PRId64 "\n", postedTime);
  91. StringAppendF(&outString, "--- Req. Present\t%" PRId64 "\n", requestedPresentTime);
  92. outString.append("--- Latched \t");
  93. if (FrameEvents::isValidTimestamp(latchTime)) {
  94. StringAppendF(&outString, "%" PRId64 "\n", latchTime);
  95. } else {
  96. outString.append("Pending\n");
  97. }
  98. outString.append("--- Refresh (First)\t");
  99. if (FrameEvents::isValidTimestamp(firstRefreshStartTime)) {
  100. StringAppendF(&outString, "%" PRId64 "\n", firstRefreshStartTime);
  101. } else {
  102. outString.append("Pending\n");
  103. }
  104. outString.append("--- Refresh (Last)\t");
  105. if (FrameEvents::isValidTimestamp(lastRefreshStartTime)) {
  106. StringAppendF(&outString, "%" PRId64 "\n", lastRefreshStartTime);
  107. } else {
  108. outString.append("Pending\n");
  109. }
  110. dumpFenceTime(outString, "Acquire \t",
  111. true, *acquireFence);
  112. dumpFenceTime(outString, "GPU Composite Done\t",
  113. !addPostCompositeCalled, *gpuCompositionDoneFence);
  114. dumpFenceTime(outString, "Display Present \t",
  115. !addPostCompositeCalled, *displayPresentFence);
  116. outString.append("--- DequeueReady \t");
  117. if (FrameEvents::isValidTimestamp(dequeueReadyTime)) {
  118. StringAppendF(&outString, "%" PRId64 "\n", dequeueReadyTime);
  119. } else {
  120. outString.append("Pending\n");
  121. }
  122. dumpFenceTime(outString, "Release \t",
  123. true, *releaseFence);
  124. }
  125. // ============================================================================
  126. // FrameEventHistory
  127. // ============================================================================
  128. namespace {
  129. struct FrameNumberEqual {
  130. explicit FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
  131. bool operator()(const FrameEvents& frame) {
  132. return frame.valid && mFrameNumber == frame.frameNumber;
  133. }
  134. const uint64_t mFrameNumber;
  135. };
  136. } // namespace
  137. FrameEventHistory::~FrameEventHistory() = default;
  138. FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber) {
  139. auto frame = std::find_if(
  140. mFrames.begin(), mFrames.end(), FrameNumberEqual(frameNumber));
  141. return frame == mFrames.end() ? nullptr : &(*frame);
  142. }
  143. FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber, size_t* iHint) {
  144. *iHint = std::min(*iHint, mFrames.size());
  145. auto hint = mFrames.begin() + *iHint;
  146. auto frame = std::find_if(
  147. hint, mFrames.end(), FrameNumberEqual(frameNumber));
  148. if (frame == mFrames.end()) {
  149. frame = std::find_if(
  150. mFrames.begin(), hint, FrameNumberEqual(frameNumber));
  151. if (frame == hint) {
  152. return nullptr;
  153. }
  154. }
  155. *iHint = static_cast<size_t>(std::distance(mFrames.begin(), frame));
  156. return &(*frame);
  157. }
  158. void FrameEventHistory::checkFencesForCompletion() {
  159. for (auto& frame : mFrames) {
  160. frame.checkFencesForCompletion();
  161. }
  162. }
  163. // Uses !|valid| as the MSB.
  164. static bool FrameNumberLessThan(
  165. const FrameEvents& lhs, const FrameEvents& rhs) {
  166. if (lhs.valid == rhs.valid) {
  167. return lhs.frameNumber < rhs.frameNumber;
  168. }
  169. return lhs.valid;
  170. }
  171. void FrameEventHistory::dump(std::string& outString) const {
  172. auto earliestFrame = std::min_element(
  173. mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
  174. if (!earliestFrame->valid) {
  175. outString.append("-- N/A\n");
  176. return;
  177. }
  178. for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
  179. frame->dump(outString);
  180. }
  181. for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
  182. frame->dump(outString);
  183. }
  184. }
  185. // ============================================================================
  186. // ProducerFrameEventHistory
  187. // ============================================================================
  188. ProducerFrameEventHistory::~ProducerFrameEventHistory() = default;
  189. nsecs_t ProducerFrameEventHistory::snapToNextTick(
  190. nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval) {
  191. nsecs_t tickOffset = (tickPhase - timestamp) % tickInterval;
  192. // Integer modulo rounds towards 0 and not -inf before taking the remainder,
  193. // so adjust the offset if it is negative.
  194. if (tickOffset < 0) {
  195. tickOffset += tickInterval;
  196. }
  197. return timestamp + tickOffset;
  198. }
  199. nsecs_t ProducerFrameEventHistory::getNextCompositeDeadline(
  200. const nsecs_t now) const{
  201. return snapToNextTick(
  202. now, mCompositorTiming.deadline, mCompositorTiming.interval);
  203. }
  204. void ProducerFrameEventHistory::updateAcquireFence(
  205. uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) {
  206. FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
  207. if (frame == nullptr) {
  208. ALOGE("updateAcquireFence: Did not find frame.");
  209. return;
  210. }
  211. if (acquire->isValid()) {
  212. mAcquireTimeline.push(acquire);
  213. frame->acquireFence = std::move(acquire);
  214. } else {
  215. // If there isn't an acquire fence, assume that buffer was
  216. // ready for the consumer when posted.
  217. frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
  218. }
  219. }
  220. void ProducerFrameEventHistory::applyDelta(
  221. const FrameEventHistoryDelta& delta) {
  222. mCompositorTiming = delta.mCompositorTiming;
  223. for (auto& d : delta.mDeltas) {
  224. // Avoid out-of-bounds access.
  225. if (CC_UNLIKELY(d.mIndex >= mFrames.size())) {
  226. ALOGE("applyDelta: Bad index.");
  227. return;
  228. }
  229. FrameEvents& frame = mFrames[d.mIndex];
  230. frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
  231. frame.addReleaseCalled = d.mAddReleaseCalled != 0;
  232. frame.postedTime = d.mPostedTime;
  233. frame.requestedPresentTime = d.mRequestedPresentTime;
  234. frame.latchTime = d.mLatchTime;
  235. frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
  236. frame.lastRefreshStartTime = d.mLastRefreshStartTime;
  237. frame.dequeueReadyTime = d.mDequeueReadyTime;
  238. if (frame.frameNumber != d.mFrameNumber) {
  239. // We got a new frame. Initialize some of the fields.
  240. frame.frameNumber = d.mFrameNumber;
  241. frame.acquireFence = FenceTime::NO_FENCE;
  242. frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
  243. frame.displayPresentFence = FenceTime::NO_FENCE;
  244. frame.releaseFence = FenceTime::NO_FENCE;
  245. // The consumer only sends valid frames.
  246. frame.valid = true;
  247. }
  248. applyFenceDelta(&mGpuCompositionDoneTimeline,
  249. &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
  250. applyFenceDelta(&mPresentTimeline,
  251. &frame.displayPresentFence, d.mDisplayPresentFence);
  252. applyFenceDelta(&mReleaseTimeline,
  253. &frame.releaseFence, d.mReleaseFence);
  254. }
  255. }
  256. void ProducerFrameEventHistory::updateSignalTimes() {
  257. mAcquireTimeline.updateSignalTimes();
  258. mGpuCompositionDoneTimeline.updateSignalTimes();
  259. mPresentTimeline.updateSignalTimes();
  260. mReleaseTimeline.updateSignalTimes();
  261. }
  262. void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
  263. std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
  264. if (CC_UNLIKELY(dst == nullptr || dst->get() == nullptr)) {
  265. ALOGE("applyFenceDelta: dst is null.");
  266. return;
  267. }
  268. switch (src.state) {
  269. case FenceTime::Snapshot::State::EMPTY:
  270. return;
  271. case FenceTime::Snapshot::State::FENCE:
  272. ALOGE_IF((*dst)->isValid(), "applyFenceDelta: Unexpected fence.");
  273. *dst = createFenceTime(src.fence);
  274. timeline->push(*dst);
  275. return;
  276. case FenceTime::Snapshot::State::SIGNAL_TIME:
  277. if ((*dst)->isValid()) {
  278. (*dst)->applyTrustedSnapshot(src);
  279. } else {
  280. *dst = std::make_shared<FenceTime>(src.signalTime);
  281. }
  282. return;
  283. }
  284. }
  285. std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
  286. const sp<Fence>& fence) const {
  287. return std::make_shared<FenceTime>(fence);
  288. }
  289. // ============================================================================
  290. // ConsumerFrameEventHistory
  291. // ============================================================================
  292. ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
  293. void ConsumerFrameEventHistory::onDisconnect() {
  294. mCurrentConnectId++;
  295. mProducerWantsEvents = false;
  296. }
  297. void ConsumerFrameEventHistory::initializeCompositorTiming(
  298. const CompositorTiming& compositorTiming) {
  299. mCompositorTiming = compositorTiming;
  300. }
  301. void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
  302. // Overwrite all fields of the frame with default values unless set here.
  303. FrameEvents newTimestamps;
  304. newTimestamps.connectId = mCurrentConnectId;
  305. newTimestamps.frameNumber = newEntry.frameNumber;
  306. newTimestamps.postedTime = newEntry.postedTime;
  307. newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
  308. newTimestamps.acquireFence = newEntry.acquireFence;
  309. newTimestamps.valid = true;
  310. mFrames[mQueueOffset] = newTimestamps;
  311. // Note: We avoid sending the acquire fence back to the caller since
  312. // they have the original one already, so there is no need to set the
  313. // acquire dirty bit.
  314. mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();
  315. mQueueOffset = (mQueueOffset + 1) % mFrames.size();
  316. }
  317. void ConsumerFrameEventHistory::addLatch(
  318. uint64_t frameNumber, nsecs_t latchTime) {
  319. FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
  320. if (frame == nullptr) {
  321. ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
  322. return;
  323. }
  324. frame->latchTime = latchTime;
  325. mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
  326. }
  327. void ConsumerFrameEventHistory::addPreComposition(
  328. uint64_t frameNumber, nsecs_t refreshStartTime) {
  329. FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
  330. if (frame == nullptr) {
  331. ALOGE_IF(mProducerWantsEvents,
  332. "addPreComposition: Did not find frame.");
  333. return;
  334. }
  335. frame->lastRefreshStartTime = refreshStartTime;
  336. mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
  337. if (!FrameEvents::isValidTimestamp(frame->firstRefreshStartTime)) {
  338. frame->firstRefreshStartTime = refreshStartTime;
  339. mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
  340. }
  341. }
  342. void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
  343. const std::shared_ptr<FenceTime>& gpuCompositionDone,
  344. const std::shared_ptr<FenceTime>& displayPresent,
  345. const CompositorTiming& compositorTiming) {
  346. mCompositorTiming = compositorTiming;
  347. FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
  348. if (frame == nullptr) {
  349. ALOGE_IF(mProducerWantsEvents,
  350. "addPostComposition: Did not find frame.");
  351. return;
  352. }
  353. // Only get GPU and present info for the first composite.
  354. if (!frame->addPostCompositeCalled) {
  355. frame->addPostCompositeCalled = true;
  356. frame->gpuCompositionDoneFence = gpuCompositionDone;
  357. mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GPU_COMPOSITION_DONE>();
  358. if (!frame->displayPresentFence->isValid()) {
  359. frame->displayPresentFence = displayPresent;
  360. mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
  361. }
  362. }
  363. }
  364. void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber,
  365. nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) {
  366. FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
  367. if (frame == nullptr) {
  368. ALOGE_IF(mProducerWantsEvents, "addRelease: Did not find frame.");
  369. return;
  370. }
  371. frame->addReleaseCalled = true;
  372. frame->dequeueReadyTime = dequeueReadyTime;
  373. frame->releaseFence = std::move(release);
  374. mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
  375. }
  376. void ConsumerFrameEventHistory::getFrameDelta(
  377. FrameEventHistoryDelta* delta,
  378. const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame) {
  379. mProducerWantsEvents = true;
  380. size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
  381. if (mFramesDirty[i].anyDirty()) {
  382. // Make sure only to send back deltas for the current connection
  383. // since the producer won't have the correct state to apply a delta
  384. // from a previous connection.
  385. if (mFrames[i].connectId == mCurrentConnectId) {
  386. delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
  387. }
  388. mFramesDirty[i].reset();
  389. }
  390. }
  391. void ConsumerFrameEventHistory::getAndResetDelta(
  392. FrameEventHistoryDelta* delta) {
  393. mProducerWantsEvents = true;
  394. delta->mCompositorTiming = mCompositorTiming;
  395. // Write these in order of frame number so that it is easy to
  396. // add them to a FenceTimeline in the proper order producer side.
  397. delta->mDeltas.reserve(mFramesDirty.size());
  398. auto earliestFrame = std::min_element(
  399. mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
  400. for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
  401. getFrameDelta(delta, frame);
  402. }
  403. for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
  404. getFrameDelta(delta, frame);
  405. }
  406. }
  407. // ============================================================================
  408. // FrameEventsDelta
  409. // ============================================================================
  410. FrameEventsDelta::FrameEventsDelta(
  411. size_t index,
  412. const FrameEvents& frameTimestamps,
  413. const FrameEventDirtyFields& dirtyFields)
  414. : mIndex(index),
  415. mFrameNumber(frameTimestamps.frameNumber),
  416. mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
  417. mAddReleaseCalled(frameTimestamps.addReleaseCalled),
  418. mPostedTime(frameTimestamps.postedTime),
  419. mRequestedPresentTime(frameTimestamps.requestedPresentTime),
  420. mLatchTime(frameTimestamps.latchTime),
  421. mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
  422. mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime),
  423. mDequeueReadyTime(frameTimestamps.dequeueReadyTime) {
  424. if (dirtyFields.isDirty<FrameEvent::GPU_COMPOSITION_DONE>()) {
  425. mGpuCompositionDoneFence =
  426. frameTimestamps.gpuCompositionDoneFence->getSnapshot();
  427. }
  428. if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
  429. mDisplayPresentFence =
  430. frameTimestamps.displayPresentFence->getSnapshot();
  431. }
  432. if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
  433. mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
  434. }
  435. }
  436. constexpr size_t FrameEventsDelta::minFlattenedSize() {
  437. return sizeof(FrameEventsDelta::mFrameNumber) +
  438. sizeof(uint16_t) + // mIndex
  439. sizeof(uint8_t) + // mAddPostCompositeCalled
  440. sizeof(uint8_t) + // mAddReleaseCalled
  441. sizeof(FrameEventsDelta::mPostedTime) +
  442. sizeof(FrameEventsDelta::mRequestedPresentTime) +
  443. sizeof(FrameEventsDelta::mLatchTime) +
  444. sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
  445. sizeof(FrameEventsDelta::mLastRefreshStartTime) +
  446. sizeof(FrameEventsDelta::mDequeueReadyTime);
  447. }
  448. // Flattenable implementation
  449. size_t FrameEventsDelta::getFlattenedSize() const {
  450. auto fences = allFences(this);
  451. return minFlattenedSize() +
  452. std::accumulate(fences.begin(), fences.end(), size_t(0),
  453. [](size_t a, const FenceTime::Snapshot* fence) {
  454. return a + fence->getFlattenedSize();
  455. });
  456. }
  457. size_t FrameEventsDelta::getFdCount() const {
  458. auto fences = allFences(this);
  459. return std::accumulate(fences.begin(), fences.end(), size_t(0),
  460. [](size_t a, const FenceTime::Snapshot* fence) {
  461. return a + fence->getFdCount();
  462. });
  463. }
  464. status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
  465. size_t& count) const {
  466. if (size < getFlattenedSize() || count < getFdCount()) {
  467. return NO_MEMORY;
  468. }
  469. if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY ||
  470. mIndex > std::numeric_limits<uint16_t>::max()) {
  471. return BAD_VALUE;
  472. }
  473. FlattenableUtils::write(buffer, size, mFrameNumber);
  474. // These are static_cast to uint16_t/uint8_t for alignment.
  475. FlattenableUtils::write(buffer, size, static_cast<uint16_t>(mIndex));
  476. FlattenableUtils::write(
  477. buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
  478. FlattenableUtils::write(
  479. buffer, size, static_cast<uint8_t>(mAddReleaseCalled));
  480. FlattenableUtils::write(buffer, size, mPostedTime);
  481. FlattenableUtils::write(buffer, size, mRequestedPresentTime);
  482. FlattenableUtils::write(buffer, size, mLatchTime);
  483. FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
  484. FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
  485. FlattenableUtils::write(buffer, size, mDequeueReadyTime);
  486. // Fences
  487. for (auto fence : allFences(this)) {
  488. status_t status = fence->flatten(buffer, size, fds, count);
  489. if (status != NO_ERROR) {
  490. return status;
  491. }
  492. }
  493. return NO_ERROR;
  494. }
  495. status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
  496. int const*& fds, size_t& count) {
  497. if (size < minFlattenedSize()) {
  498. return NO_MEMORY;
  499. }
  500. FlattenableUtils::read(buffer, size, mFrameNumber);
  501. // These were written as uint16_t/uint8_t for alignment.
  502. uint16_t temp16 = 0;
  503. FlattenableUtils::read(buffer, size, temp16);
  504. mIndex = temp16;
  505. if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY) {
  506. return BAD_VALUE;
  507. }
  508. uint8_t temp8 = 0;
  509. FlattenableUtils::read(buffer, size, temp8);
  510. mAddPostCompositeCalled = static_cast<bool>(temp8);
  511. FlattenableUtils::read(buffer, size, temp8);
  512. mAddReleaseCalled = static_cast<bool>(temp8);
  513. FlattenableUtils::read(buffer, size, mPostedTime);
  514. FlattenableUtils::read(buffer, size, mRequestedPresentTime);
  515. FlattenableUtils::read(buffer, size, mLatchTime);
  516. FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
  517. FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
  518. FlattenableUtils::read(buffer, size, mDequeueReadyTime);
  519. // Fences
  520. for (auto fence : allFences(this)) {
  521. status_t status = fence->unflatten(buffer, size, fds, count);
  522. if (status != NO_ERROR) {
  523. return status;
  524. }
  525. }
  526. return NO_ERROR;
  527. }
  528. // ============================================================================
  529. // FrameEventHistoryDelta
  530. // ============================================================================
  531. FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
  532. FrameEventHistoryDelta&& src) noexcept {
  533. mCompositorTiming = src.mCompositorTiming;
  534. if (CC_UNLIKELY(!mDeltas.empty())) {
  535. ALOGE("FrameEventHistoryDelta assign clobbering history.");
  536. }
  537. mDeltas = std::move(src.mDeltas);
  538. return *this;
  539. }
  540. constexpr size_t FrameEventHistoryDelta::minFlattenedSize() {
  541. return sizeof(uint32_t) + // mDeltas.size()
  542. sizeof(mCompositorTiming);
  543. }
  544. size_t FrameEventHistoryDelta::getFlattenedSize() const {
  545. return minFlattenedSize() +
  546. std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
  547. [](size_t a, const FrameEventsDelta& delta) {
  548. return a + delta.getFlattenedSize();
  549. });
  550. }
  551. size_t FrameEventHistoryDelta::getFdCount() const {
  552. return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
  553. [](size_t a, const FrameEventsDelta& delta) {
  554. return a + delta.getFdCount();
  555. });
  556. }
  557. status_t FrameEventHistoryDelta::flatten(
  558. void*& buffer, size_t& size, int*& fds, size_t& count) const {
  559. if (mDeltas.size() > FrameEventHistory::MAX_FRAME_HISTORY) {
  560. return BAD_VALUE;
  561. }
  562. if (size < getFlattenedSize()) {
  563. return NO_MEMORY;
  564. }
  565. FlattenableUtils::write(buffer, size, mCompositorTiming);
  566. FlattenableUtils::write(
  567. buffer, size, static_cast<uint32_t>(mDeltas.size()));
  568. for (auto& d : mDeltas) {
  569. status_t status = d.flatten(buffer, size, fds, count);
  570. if (status != NO_ERROR) {
  571. return status;
  572. }
  573. }
  574. return NO_ERROR;
  575. }
  576. status_t FrameEventHistoryDelta::unflatten(
  577. void const*& buffer, size_t& size, int const*& fds, size_t& count) {
  578. if (size < minFlattenedSize()) {
  579. return NO_MEMORY;
  580. }
  581. FlattenableUtils::read(buffer, size, mCompositorTiming);
  582. uint32_t deltaCount = 0;
  583. FlattenableUtils::read(buffer, size, deltaCount);
  584. if (deltaCount > FrameEventHistory::MAX_FRAME_HISTORY) {
  585. return BAD_VALUE;
  586. }
  587. mDeltas.resize(deltaCount);
  588. for (auto& d : mDeltas) {
  589. status_t status = d.unflatten(buffer, size, fds, count);
  590. if (status != NO_ERROR) {
  591. return status;
  592. }
  593. }
  594. return NO_ERROR;
  595. }
  596. } // namespace android