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