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