/*
* 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) {
        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
