/*
* Copyright 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <gui/FrameTimestamps.h>

#define LOG_TAG "FrameEvents"

#include <LibGuiProperties.sysprop.h>
#include <android-base/stringprintf.h>
#include <cutils/compiler.h>  // For CC_[UN]LIKELY
#include <inttypes.h>
#include <utils/Log.h>

#include <algorithm>
#include <limits>
#include <numeric>

namespace android {

using base::StringAppendF;

// ============================================================================
// FrameEvents
// ============================================================================

bool FrameEvents::hasPostedInfo() const {
    return FrameEvents::isValidTimestamp(postedTime);
}

bool FrameEvents::hasRequestedPresentInfo() const {
    return FrameEvents::isValidTimestamp(requestedPresentTime);
}

bool FrameEvents::hasLatchInfo() const {
    return FrameEvents::isValidTimestamp(latchTime);
}

bool FrameEvents::hasFirstRefreshStartInfo() const {
    return FrameEvents::isValidTimestamp(firstRefreshStartTime);
}

bool FrameEvents::hasLastRefreshStartInfo() const {
    // The last refresh start time may continue to update until a new frame
    // is latched. We know we have the final value once the release info is set.
    return addReleaseCalled;
}

bool FrameEvents::hasDequeueReadyInfo() const {
    return FrameEvents::isValidTimestamp(dequeueReadyTime);
}

bool FrameEvents::hasAcquireInfo() const {
    return acquireFence->isValid();
}

bool FrameEvents::hasGpuCompositionDoneInfo() const {
    // We may not get a gpuCompositionDone in addPostComposite if
    // client/gles compositing isn't needed.
    return addPostCompositeCalled;
}

bool FrameEvents::hasDisplayPresentInfo() const {
    // We may not get a displayPresent in addPostComposite for HWC1.
    return addPostCompositeCalled;
}

bool FrameEvents::hasReleaseInfo() const {
    return addReleaseCalled;
}

void FrameEvents::checkFencesForCompletion() {
    acquireFence->getSignalTime();
    gpuCompositionDoneFence->getSignalTime();
    displayPresentFence->getSignalTime();
    releaseFence->getSignalTime();
}

static void dumpFenceTime(std::string& outString, const char* name, bool pending,
                          const FenceTime& fenceTime) {
    StringAppendF(&outString, "--- %s", name);
    nsecs_t signalTime = fenceTime.getCachedSignalTime();
    if (Fence::isValidTimestamp(signalTime)) {
        StringAppendF(&outString, "%" PRId64 "\n", signalTime);
    } else if (pending || signalTime == Fence::SIGNAL_TIME_PENDING) {
        outString.append("Pending\n");
    } else if (&fenceTime == FenceTime::NO_FENCE.get()){
        outString.append("N/A\n");
    } else {
        outString.append("Error\n");
    }
}

void FrameEvents::dump(std::string& outString) const {
    if (!valid) {
        return;
    }

    StringAppendF(&outString, "-- Frame %" PRIu64 "\n", frameNumber);
    StringAppendF(&outString, "--- Posted      \t%" PRId64 "\n", postedTime);
    StringAppendF(&outString, "--- Req. Present\t%" PRId64 "\n", requestedPresentTime);

    outString.append("--- Latched     \t");
    if (FrameEvents::isValidTimestamp(latchTime)) {
        StringAppendF(&outString, "%" PRId64 "\n", latchTime);
    } else {
        outString.append("Pending\n");
    }

    outString.append("--- Refresh (First)\t");
    if (FrameEvents::isValidTimestamp(firstRefreshStartTime)) {
        StringAppendF(&outString, "%" PRId64 "\n", firstRefreshStartTime);
    } else {
        outString.append("Pending\n");
    }

    outString.append("--- Refresh (Last)\t");
    if (FrameEvents::isValidTimestamp(lastRefreshStartTime)) {
        StringAppendF(&outString, "%" PRId64 "\n", lastRefreshStartTime);
    } else {
        outString.append("Pending\n");
    }

    dumpFenceTime(outString, "Acquire           \t",
            true, *acquireFence);
    dumpFenceTime(outString, "GPU Composite Done\t",
            !addPostCompositeCalled, *gpuCompositionDoneFence);
    dumpFenceTime(outString, "Display Present   \t",
            !addPostCompositeCalled, *displayPresentFence);

    outString.append("--- DequeueReady  \t");
    if (FrameEvents::isValidTimestamp(dequeueReadyTime)) {
        StringAppendF(&outString, "%" PRId64 "\n", dequeueReadyTime);
    } else {
        outString.append("Pending\n");
    }

    dumpFenceTime(outString, "Release           \t",
            true, *releaseFence);
}


// ============================================================================
// FrameEventHistory
// ============================================================================

namespace {

struct FrameNumberEqual {
    explicit FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
    bool operator()(const FrameEvents& frame) {
        return frame.valid && mFrameNumber == frame.frameNumber;
    }
    const uint64_t mFrameNumber;
};

}  // namespace

const size_t FrameEventHistory::INITIAL_MAX_FRAME_HISTORY =
        sysprop::LibGuiProperties::frame_event_history_size().value_or(8);

FrameEventHistory::FrameEventHistory()
      : mFrames(std::vector<FrameEvents>(INITIAL_MAX_FRAME_HISTORY)) {}

FrameEventHistory::~FrameEventHistory() = default;

FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber) {
    auto frame = std::find_if(
            mFrames.begin(), mFrames.end(), FrameNumberEqual(frameNumber));
    return frame == mFrames.end() ? nullptr : &(*frame);
}

FrameEvents* FrameEventHistory::getFrame(uint64_t frameNumber, size_t* iHint) {
    *iHint = std::min(*iHint, mFrames.size());
    auto hint = mFrames.begin() + *iHint;
    auto frame = std::find_if(
            hint, mFrames.end(), FrameNumberEqual(frameNumber));
    if (frame == mFrames.end()) {
        frame = std::find_if(
                mFrames.begin(), hint, FrameNumberEqual(frameNumber));
        if (frame == hint) {
            return nullptr;
        }
    }
    *iHint = static_cast<size_t>(std::distance(mFrames.begin(), frame));
    return &(*frame);
}

void FrameEventHistory::checkFencesForCompletion() {
    for (auto& frame : mFrames) {
        frame.checkFencesForCompletion();
    }
}

// Uses !|valid| as the MSB.
static bool FrameNumberLessThan(
        const FrameEvents& lhs, const FrameEvents& rhs) {
    if (lhs.valid == rhs.valid) {
        return lhs.frameNumber < rhs.frameNumber;
    }
    return lhs.valid;
}

void FrameEventHistory::dump(std::string& outString) const {
    auto earliestFrame = std::min_element(
            mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
    if (!earliestFrame->valid) {
        outString.append("-- N/A\n");
        return;
    }
    for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
        frame->dump(outString);
    }
    for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
        frame->dump(outString);
    }
}

// ============================================================================
// ProducerFrameEventHistory
// ============================================================================

ProducerFrameEventHistory::~ProducerFrameEventHistory() = default;

nsecs_t ProducerFrameEventHistory::snapToNextTick(
        nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval) {
    nsecs_t tickOffset = (tickPhase - timestamp) % tickInterval;
    // Integer modulo rounds towards 0 and not -inf before taking the remainder,
    // so adjust the offset if it is negative.
    if (tickOffset < 0) {
        tickOffset += tickInterval;
    }
    return timestamp + tickOffset;
}

nsecs_t ProducerFrameEventHistory::getNextCompositeDeadline(
        const nsecs_t now) const{
    return snapToNextTick(
            now, mCompositorTiming.deadline, mCompositorTiming.interval);
}

void ProducerFrameEventHistory::updateAcquireFence(
        uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) {
    FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset);
    if (frame == nullptr) {
        ALOGE("updateAcquireFence: Did not find frame.");
        return;
    }

    if (acquire->isValid()) {
        mAcquireTimeline.push(acquire);
        frame->acquireFence = std::move(acquire);
    } else {
        // If there isn't an acquire fence, assume that buffer was
        // ready for the consumer when posted.
        frame->acquireFence = std::make_shared<FenceTime>(frame->postedTime);
    }
}

void ProducerFrameEventHistory::applyDelta(
        const FrameEventHistoryDelta& delta) {
    mCompositorTiming = delta.mCompositorTiming;

    // Deltas should have enough reserved capacity for the consumer-side, therefore if there's a
    // different capacity, we re-sized on the consumer side and now need to resize on the producer
    // side.
    if (delta.mDeltas.capacity() > mFrames.capacity()) {
        resize(delta.mDeltas.capacity());
    }

    for (auto& d : delta.mDeltas) {
        // Avoid out-of-bounds access.
        if (CC_UNLIKELY(d.mIndex >= mFrames.size())) {
            ALOGE("applyDelta: Bad index.");
            return;
        }

        FrameEvents& frame = mFrames[d.mIndex];

        frame.addPostCompositeCalled = d.mAddPostCompositeCalled != 0;
        frame.addReleaseCalled = d.mAddReleaseCalled != 0;

        frame.postedTime = d.mPostedTime;
        frame.requestedPresentTime = d.mRequestedPresentTime;
        frame.latchTime = d.mLatchTime;
        frame.firstRefreshStartTime = d.mFirstRefreshStartTime;
        frame.lastRefreshStartTime = d.mLastRefreshStartTime;
        frame.dequeueReadyTime = d.mDequeueReadyTime;

        if (frame.frameNumber != d.mFrameNumber) {
            // We got a new frame. Initialize some of the fields.
            frame.frameNumber = d.mFrameNumber;
            frame.acquireFence = FenceTime::NO_FENCE;
            frame.gpuCompositionDoneFence = FenceTime::NO_FENCE;
            frame.displayPresentFence = FenceTime::NO_FENCE;
            frame.releaseFence = FenceTime::NO_FENCE;
            // The consumer only sends valid frames.
            frame.valid = true;
        }

        applyFenceDelta(&mGpuCompositionDoneTimeline,
                &frame.gpuCompositionDoneFence, d.mGpuCompositionDoneFence);
        applyFenceDelta(&mPresentTimeline,
                &frame.displayPresentFence, d.mDisplayPresentFence);
        applyFenceDelta(&mReleaseTimeline,
                &frame.releaseFence, d.mReleaseFence);
    }
}

void ProducerFrameEventHistory::updateSignalTimes() {
    mAcquireTimeline.updateSignalTimes();
    mGpuCompositionDoneTimeline.updateSignalTimes();
    mPresentTimeline.updateSignalTimes();
    mReleaseTimeline.updateSignalTimes();
}

void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline,
        std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const {
    if (CC_UNLIKELY(dst == nullptr || dst->get() == nullptr)) {
        ALOGE("applyFenceDelta: dst is null.");
        return;
    }

    switch (src.state) {
        case FenceTime::Snapshot::State::EMPTY:
            return;
        case FenceTime::Snapshot::State::FENCE:
            ALOGE_IF((*dst)->isValid(), "applyFenceDelta: Unexpected fence.");
            *dst = createFenceTime(src.fence);
            timeline->push(*dst);
            return;
        case FenceTime::Snapshot::State::SIGNAL_TIME:
            if ((*dst)->isValid()) {
                (*dst)->applyTrustedSnapshot(src);
            } else {
                *dst = std::make_shared<FenceTime>(src.signalTime);
            }
            return;
    }
}

std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
        const sp<Fence>& fence) const {
    return std::make_shared<FenceTime>(fence);
}

void ProducerFrameEventHistory::resize(size_t newSize) {
    // we don't want to drop events by resizing too small, so don't resize in the negative direction
    if (newSize <= mFrames.size()) {
        return;
    }

    // This algorithm for resizing needs to be the same as ConsumerFrameEventHistory::resize,
    // because the indexes need to match when communicating the FrameEventDeltas.

    // We need to find the oldest frame, because that frame needs to move to index 0 in the new
    // frame history.
    size_t oldestFrameIndex = 0;
    size_t oldestFrameNumber = INT32_MAX;
    for (size_t i = 0; i < mFrames.size(); ++i) {
        if (mFrames[i].frameNumber < oldestFrameNumber && mFrames[i].valid) {
            oldestFrameNumber = mFrames[i].frameNumber;
            oldestFrameIndex = i;
        }
    }

    // move the existing frame information into a new vector, so that the oldest frames are at
    // index 0, and the latest frames are at the end of the vector
    std::vector<FrameEvents> newFrames(newSize);
    size_t oldI = oldestFrameIndex;
    size_t newI = 0;
    do {
        if (mFrames[oldI].valid) {
            newFrames[newI++] = std::move(mFrames[oldI]);
        }
        oldI = (oldI + 1) % mFrames.size();
    } while (oldI != oldestFrameIndex);

    mFrames = std::move(newFrames);
    mAcquireOffset = 0; // this is just a hint, so setting this to anything is fine
}

// ============================================================================
// ConsumerFrameEventHistory
// ============================================================================

ConsumerFrameEventHistory::ConsumerFrameEventHistory()
      : mFramesDirty(std::vector<FrameEventDirtyFields>(INITIAL_MAX_FRAME_HISTORY)) {}

ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;

void ConsumerFrameEventHistory::onDisconnect() {
    mCurrentConnectId++;
    mProducerWantsEvents = false;
}

void ConsumerFrameEventHistory::setProducerWantsEvents() {
    mProducerWantsEvents = true;
}

void ConsumerFrameEventHistory::initializeCompositorTiming(
        const CompositorTiming& compositorTiming) {
    mCompositorTiming = compositorTiming;
}

void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) {
    // Overwrite all fields of the frame with default values unless set here.
    FrameEvents newTimestamps;
    newTimestamps.connectId = mCurrentConnectId;
    newTimestamps.frameNumber = newEntry.frameNumber;
    newTimestamps.postedTime = newEntry.postedTime;
    newTimestamps.requestedPresentTime = newEntry.requestedPresentTime;
    newTimestamps.acquireFence = newEntry.acquireFence;
    newTimestamps.valid = true;
    mFrames[mQueueOffset] = newTimestamps;

    // Note: We avoid sending the acquire fence back to the caller since
    // they have the original one already, so there is no need to set the
    // acquire dirty bit.
    mFramesDirty[mQueueOffset].setDirty<FrameEvent::POSTED>();

    mQueueOffset = (mQueueOffset + 1) % mFrames.size();
}

void ConsumerFrameEventHistory::addLatch(
        uint64_t frameNumber, nsecs_t latchTime) {
    FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
    if (frame == nullptr) {
        ALOGE_IF(mProducerWantsEvents, "addLatch: Did not find frame.");
        return;
    }
    frame->latchTime = latchTime;
    mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LATCH>();
}

void ConsumerFrameEventHistory::addPreComposition(
        uint64_t frameNumber, nsecs_t refreshStartTime) {
    FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
    if (frame == nullptr) {
        ALOGE_IF(mProducerWantsEvents,
                "addPreComposition: Did not find frame.");
        return;
    }
    frame->lastRefreshStartTime = refreshStartTime;
    mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>();
    if (!FrameEvents::isValidTimestamp(frame->firstRefreshStartTime)) {
        frame->firstRefreshStartTime = refreshStartTime;
        mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>();
    }
}

void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber,
        const std::shared_ptr<FenceTime>& gpuCompositionDone,
        const std::shared_ptr<FenceTime>& displayPresent,
        const CompositorTiming& compositorTiming) {
    mCompositorTiming = compositorTiming;

    FrameEvents* frame = getFrame(frameNumber, &mCompositionOffset);
    if (frame == nullptr) {
        ALOGE_IF(mProducerWantsEvents,
                "addPostComposition: Did not find frame.");
        return;
    }
    // Only get GPU and present info for the first composite.
    if (!frame->addPostCompositeCalled) {
        frame->addPostCompositeCalled = true;
        frame->gpuCompositionDoneFence = gpuCompositionDone;
        mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GPU_COMPOSITION_DONE>();
        if (!frame->displayPresentFence->isValid()) {
            frame->displayPresentFence = displayPresent;
            mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>();
        }
    }
}

void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber,
        nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) {
    FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset);
    if (frame == nullptr) {
        ALOGE_IF(mProducerWantsEvents, "addRelease: Did not find frame.");
        return;
    }
    frame->addReleaseCalled = true;
    frame->dequeueReadyTime = dequeueReadyTime;
    frame->releaseFence = std::move(release);
    mFramesDirty[mReleaseOffset].setDirty<FrameEvent::RELEASE>();
}

void ConsumerFrameEventHistory::getFrameDelta(FrameEventHistoryDelta* delta,
                                              const std::vector<FrameEvents>::iterator& frame) {
    mProducerWantsEvents = true;
    size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame));
    if (mFramesDirty[i].anyDirty()) {
        // Make sure only to send back deltas for the current connection
        // since the producer won't have the correct state to apply a delta
        // from a previous connection.
        if (mFrames[i].connectId == mCurrentConnectId) {
            delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]);
        }
        mFramesDirty[i].reset();
    }
}

void ConsumerFrameEventHistory::getAndResetDelta(
        FrameEventHistoryDelta* delta) {
    mProducerWantsEvents = true;
    delta->mCompositorTiming = mCompositorTiming;

    // Write these in order of frame number so that it is easy to
    // add them to a FenceTimeline in the proper order producer side.
    delta->mDeltas.reserve(mFramesDirty.size());
    auto earliestFrame = std::min_element(
            mFrames.begin(), mFrames.end(), &FrameNumberLessThan);
    for (auto frame = earliestFrame; frame != mFrames.end(); ++frame) {
        getFrameDelta(delta, frame);
    }
    for (auto frame = mFrames.begin(); frame != earliestFrame; ++frame) {
        getFrameDelta(delta, frame);
    }
}

void ConsumerFrameEventHistory::resize(size_t newSize) {
    // we don't want to drop events by resizing too small, so don't resize in the negative direction
    if (newSize <= mFrames.size()) {
        return;
    }

    // This algorithm for resizing needs to be the same as ProducerFrameEventHistory::resize,
    // because the indexes need to match when communicating the FrameEventDeltas.

    // move the existing frame information into a new vector, so that the oldest frames are at
    // index 0, and the latest frames are towards the end of the vector
    std::vector<FrameEvents> newFrames(newSize);
    std::vector<FrameEventDirtyFields> newFramesDirty(newSize);
    size_t oldestFrameIndex = mQueueOffset;
    size_t oldI = oldestFrameIndex;
    size_t newI = 0;
    do {
        if (mFrames[oldI].valid) {
            newFrames[newI] = std::move(mFrames[oldI]);
            newFramesDirty[newI] = mFramesDirty[oldI];
            newI += 1;
        }
        oldI = (oldI + 1) % mFrames.size();
    } while (oldI != oldestFrameIndex);

    mFrames = std::move(newFrames);
    mFramesDirty = std::move(newFramesDirty);
    mQueueOffset = newI;
    mCompositionOffset = 0; // this is just a hint, so setting this to anything is fine
}

// ============================================================================
// FrameEventsDelta
// ============================================================================

FrameEventsDelta::FrameEventsDelta(
        size_t index,
        const FrameEvents& frameTimestamps,
        const FrameEventDirtyFields& dirtyFields)
    : mIndex(index),
      mFrameNumber(frameTimestamps.frameNumber),
      mAddPostCompositeCalled(frameTimestamps.addPostCompositeCalled),
      mAddReleaseCalled(frameTimestamps.addReleaseCalled),
      mPostedTime(frameTimestamps.postedTime),
      mRequestedPresentTime(frameTimestamps.requestedPresentTime),
      mLatchTime(frameTimestamps.latchTime),
      mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime),
      mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime),
      mDequeueReadyTime(frameTimestamps.dequeueReadyTime) {
    if (dirtyFields.isDirty<FrameEvent::GPU_COMPOSITION_DONE>()) {
        mGpuCompositionDoneFence =
                frameTimestamps.gpuCompositionDoneFence->getSnapshot();
    }
    if (dirtyFields.isDirty<FrameEvent::DISPLAY_PRESENT>()) {
        mDisplayPresentFence =
                frameTimestamps.displayPresentFence->getSnapshot();
    }
    if (dirtyFields.isDirty<FrameEvent::RELEASE>()) {
        mReleaseFence = frameTimestamps.releaseFence->getSnapshot();
    }
}

constexpr size_t FrameEventsDelta::minFlattenedSize() {
    return sizeof(FrameEventsDelta::mFrameNumber) +
            sizeof(uint16_t) + // mIndex
            sizeof(uint8_t) + // mAddPostCompositeCalled
            sizeof(uint8_t) + // mAddReleaseCalled
            sizeof(FrameEventsDelta::mPostedTime) +
            sizeof(FrameEventsDelta::mRequestedPresentTime) +
            sizeof(FrameEventsDelta::mLatchTime) +
            sizeof(FrameEventsDelta::mFirstRefreshStartTime) +
            sizeof(FrameEventsDelta::mLastRefreshStartTime) +
            sizeof(FrameEventsDelta::mDequeueReadyTime);
}

// Flattenable implementation
size_t FrameEventsDelta::getFlattenedSize() const {
    auto fences = allFences(this);
    return minFlattenedSize() +
            std::accumulate(fences.begin(), fences.end(), size_t(0),
                    [](size_t a, const FenceTime::Snapshot* fence) {
                            return a + fence->getFlattenedSize();
                    });
}

size_t FrameEventsDelta::getFdCount() const {
    auto fences = allFences(this);
    return std::accumulate(fences.begin(), fences.end(), size_t(0),
            [](size_t a, const FenceTime::Snapshot* fence) {
                return a + fence->getFdCount();
            });
}

status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
            size_t& count) const {
    if (size < getFlattenedSize() || count < getFdCount()) {
        return NO_MEMORY;
    }

    if (mIndex >= UINT8_MAX || mIndex < 0) {
        return BAD_VALUE;
    }

    FlattenableUtils::write(buffer, size, mFrameNumber);

    // These are static_cast to uint16_t/uint8_t for alignment.
    FlattenableUtils::write(buffer, size, static_cast<uint16_t>(mIndex));
    FlattenableUtils::write(
            buffer, size, static_cast<uint8_t>(mAddPostCompositeCalled));
    FlattenableUtils::write(
            buffer, size, static_cast<uint8_t>(mAddReleaseCalled));

    FlattenableUtils::write(buffer, size, mPostedTime);
    FlattenableUtils::write(buffer, size, mRequestedPresentTime);
    FlattenableUtils::write(buffer, size, mLatchTime);
    FlattenableUtils::write(buffer, size, mFirstRefreshStartTime);
    FlattenableUtils::write(buffer, size, mLastRefreshStartTime);
    FlattenableUtils::write(buffer, size, mDequeueReadyTime);

    // Fences
    for (auto fence : allFences(this)) {
        status_t status = fence->flatten(buffer, size, fds, count);
        if (status != NO_ERROR) {
            return status;
        }
    }
    return NO_ERROR;
}

status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
            int const*& fds, size_t& count) {
    if (size < minFlattenedSize()) {
        return NO_MEMORY;
    }

    FlattenableUtils::read(buffer, size, mFrameNumber);

    // These were written as uint16_t/uint8_t for alignment.
    uint16_t temp16 = 0;
    FlattenableUtils::read(buffer, size, temp16);
    mIndex = temp16;
    if (mIndex >= UINT8_MAX) {
        return BAD_VALUE;
    }
    uint8_t temp8 = 0;
    FlattenableUtils::read(buffer, size, temp8);
    mAddPostCompositeCalled = static_cast<bool>(temp8);
    FlattenableUtils::read(buffer, size, temp8);
    mAddReleaseCalled = static_cast<bool>(temp8);

    FlattenableUtils::read(buffer, size, mPostedTime);
    FlattenableUtils::read(buffer, size, mRequestedPresentTime);
    FlattenableUtils::read(buffer, size, mLatchTime);
    FlattenableUtils::read(buffer, size, mFirstRefreshStartTime);
    FlattenableUtils::read(buffer, size, mLastRefreshStartTime);
    FlattenableUtils::read(buffer, size, mDequeueReadyTime);

    // Fences
    for (auto fence : allFences(this)) {
        status_t status = fence->unflatten(buffer, size, fds, count);
        if (status != NO_ERROR) {
            return status;
        }
    }
    return NO_ERROR;
}

uint64_t FrameEventsDelta::getFrameNumber() const {
    return mFrameNumber;
}

bool FrameEventsDelta::getLatchTime(nsecs_t* latchTime) const {
    if (mLatchTime == FrameEvents::TIMESTAMP_PENDING) {
        return false;
    }
    *latchTime = mLatchTime;
    return true;
}

bool FrameEventsDelta::getDisplayPresentFence(sp<Fence>* fence) const {
    if (mDisplayPresentFence.fence == Fence::NO_FENCE) {
        return false;
    }
    *fence = mDisplayPresentFence.fence;
    return true;
}

// ============================================================================
// FrameEventHistoryDelta
// ============================================================================

FrameEventHistoryDelta& FrameEventHistoryDelta::operator=(
        FrameEventHistoryDelta&& src) noexcept {
    mCompositorTiming = src.mCompositorTiming;

    if (CC_UNLIKELY(!mDeltas.empty())) {
        ALOGE("FrameEventHistoryDelta assign clobbering history.");
    }
    mDeltas = std::move(src.mDeltas);
    return *this;
}

constexpr size_t FrameEventHistoryDelta::minFlattenedSize() {
    return sizeof(uint32_t) + // mDeltas.size()
            sizeof(mCompositorTiming);
}

size_t FrameEventHistoryDelta::getFlattenedSize() const {
    return minFlattenedSize() +
            std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
                    [](size_t a, const FrameEventsDelta& delta) {
                            return a + delta.getFlattenedSize();
                    });
}

size_t FrameEventHistoryDelta::getFdCount() const {
    return std::accumulate(mDeltas.begin(), mDeltas.end(), size_t(0),
            [](size_t a, const FrameEventsDelta& delta) {
                    return a + delta.getFdCount();
            });
}

status_t FrameEventHistoryDelta::flatten(
            void*& buffer, size_t& size, int*& fds, size_t& count) const {
    if (mDeltas.size() > UINT8_MAX) {
        return BAD_VALUE;
    }
    if (size < getFlattenedSize()) {
        return NO_MEMORY;
    }

    FlattenableUtils::write(buffer, size, mCompositorTiming);

    FlattenableUtils::write(
            buffer, size, static_cast<uint32_t>(mDeltas.size()));
    for (auto& d : mDeltas) {
        status_t status = d.flatten(buffer, size, fds, count);
        if (status != NO_ERROR) {
            return status;
        }
    }
    return NO_ERROR;
}

status_t FrameEventHistoryDelta::unflatten(
            void const*& buffer, size_t& size, int const*& fds, size_t& count) {
    if (size < minFlattenedSize()) {
        return NO_MEMORY;
    }

    FlattenableUtils::read(buffer, size, mCompositorTiming);

    uint32_t deltaCount = 0;
    FlattenableUtils::read(buffer, size, deltaCount);
    if (deltaCount > UINT8_MAX) {
        return BAD_VALUE;
    }
    mDeltas.resize(deltaCount);
    for (auto& d : mDeltas) {
        status_t status = d.unflatten(buffer, size, fds, count);
        if (status != NO_ERROR) {
            return status;
        }
    }
    return NO_ERROR;
}

std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::begin() const {
    return mDeltas.begin();
}

std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::end() const {
    return mDeltas.end();
}

} // namespace android
