/*
 * 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.
 */

#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include <inttypes.h>
#include "FenceTracker.h"
#include "Layer.h"
#include <utils/Trace.h>

namespace android {

FenceTracker::FenceTracker() :
        mFrameCounter(0),
        mOffset(0),
        mFrames() {}

void FenceTracker::dump(String8* outString) {
    Mutex::Autolock lock(mMutex);
    checkFencesForCompletion();

    for (size_t i = 0; i < MAX_FRAME_HISTORY; i++) {
        int index = (mOffset + i) % MAX_FRAME_HISTORY;
        const FrameRecord& frame = mFrames[index];

        outString->appendFormat("Frame %" PRIu64 "\n", frame.frameId);
        outString->appendFormat("- Refresh start\t%" PRId64 "\n",
                frame.refreshStartTime);

        if (frame.glesCompositionDoneTime) {
            outString->appendFormat("- GLES done\t%" PRId64 "\n",
                    frame.glesCompositionDoneTime);
        } else if (frame.glesCompositionDoneFence != Fence::NO_FENCE) {
            outString->append("- GLES done\tNot signaled\n");
        }
        if (frame.retireTime) {
            outString->appendFormat("- Retire\t%" PRId64 "\n",
                    frame.retireTime);
        } else {
            outString->append("- Retire\tNot signaled\n");
        }
        for (const auto& kv : frame.layers) {
            const LayerRecord& layer = kv.second;
            outString->appendFormat("-- %s\n", layer.name.string());
            outString->appendFormat("---- Frame # %" PRIu64 " (%s)\n",
                    layer.frameNumber,
                    layer.isGlesComposition ? "GLES" : "HWC");
            outString->appendFormat("---- Posted\t%" PRId64 "\n",
                    layer.postedTime);
            if (layer.acquireTime) {
                outString->appendFormat("---- Acquire\t%" PRId64 "\n",
                        layer.acquireTime);
            } else {
                outString->append("---- Acquire\tNot signaled\n");
            }
            if (layer.releaseTime) {
                outString->appendFormat("---- Release\t%" PRId64 "\n",
                        layer.releaseTime);
            } else {
                outString->append("---- Release\tNot signaled\n");
            }
        }
    }
}

static inline bool isValidTimestamp(nsecs_t time) {
    return time > 0 && time < INT64_MAX;
}

void FenceTracker::checkFencesForCompletion() {
    ATRACE_CALL();
    for (auto& frame : mFrames) {
        if (frame.retireFence != Fence::NO_FENCE) {
            nsecs_t time = frame.retireFence->getSignalTime();
            if (isValidTimestamp(time)) {
                frame.retireTime = time;
                frame.retireFence = Fence::NO_FENCE;
            }
        }
        if (frame.glesCompositionDoneFence != Fence::NO_FENCE) {
            nsecs_t time = frame.glesCompositionDoneFence->getSignalTime();
            if (isValidTimestamp(time)) {
                frame.glesCompositionDoneTime = time;
                frame.glesCompositionDoneFence = Fence::NO_FENCE;
            }
        }
        for (auto& kv : frame.layers) {
            LayerRecord& layer = kv.second;
            if (layer.acquireFence != Fence::NO_FENCE) {
                nsecs_t time = layer.acquireFence->getSignalTime();
                if (isValidTimestamp(time)) {
                    layer.acquireTime = time;
                    layer.acquireFence = Fence::NO_FENCE;
                }
            }
            if (layer.releaseFence != Fence::NO_FENCE) {
                nsecs_t time = layer.releaseFence->getSignalTime();
                if (isValidTimestamp(time)) {
                    layer.releaseTime = time;
                    layer.releaseFence = Fence::NO_FENCE;
                }
            }
        }
    }
}

void FenceTracker::addFrame(nsecs_t refreshStartTime, sp<Fence> retireFence,
        const Vector<sp<Layer>>& layers, sp<Fence> glDoneFence) {
    ATRACE_CALL();
    Mutex::Autolock lock(mMutex);
    FrameRecord& frame = mFrames[mOffset];
    FrameRecord& prevFrame = mFrames[(mOffset + MAX_FRAME_HISTORY - 1) %
                                     MAX_FRAME_HISTORY];
    frame.layers.clear();

    bool wasGlesCompositionDone = false;
    const size_t count = layers.size();
    for (size_t i = 0; i < count; i++) {
        String8 name;
        uint64_t frameNumber;
        bool glesComposition;
        nsecs_t postedTime;
        sp<Fence> acquireFence;
        sp<Fence> prevReleaseFence;
        int32_t key = layers[i]->getSequence();

        layers[i]->getFenceData(&name, &frameNumber, &glesComposition,
                &postedTime, &acquireFence, &prevReleaseFence);
#ifdef USE_HWC2
        if (glesComposition) {
            frame.layers.emplace(std::piecewise_construct,
                    std::forward_as_tuple(key),
                    std::forward_as_tuple(name, frameNumber, glesComposition,
                    postedTime, 0, 0, acquireFence, prevReleaseFence));
            wasGlesCompositionDone = true;
        } else {
            frame.layers.emplace(std::piecewise_construct,
                    std::forward_as_tuple(key),
                    std::forward_as_tuple(name, frameNumber, glesComposition,
                    postedTime, 0, 0, acquireFence, Fence::NO_FENCE));

            auto prevLayer = prevFrame.layers.find(key);
            if (prevLayer != prevFrame.layers.end()) {
                prevLayer->second.releaseFence = prevReleaseFence;
            }
        }
#else
        frame.layers.emplace(std::piecewise_construct,
                std::forward_as_tuple(key),
                std::forward_as_tuple(name, frameNumber, glesComposition,
                postedTime, 0, 0, acquireFence,
                glesComposition ? Fence::NO_FENCE : prevReleaseFence));
        if (glesComposition) {
            wasGlesCompositionDone = true;
        }
#endif
        frame.layers.emplace(std::piecewise_construct,
                std::forward_as_tuple(key),
                std::forward_as_tuple(name, frameNumber, glesComposition,
                postedTime, 0, 0, acquireFence, prevReleaseFence));
    }

    frame.frameId = mFrameCounter;
    frame.refreshStartTime = refreshStartTime;
    frame.retireTime = 0;
    frame.glesCompositionDoneTime = 0;
    prevFrame.retireFence = retireFence;
    frame.retireFence = Fence::NO_FENCE;
    frame.glesCompositionDoneFence = wasGlesCompositionDone ? glDoneFence :
            Fence::NO_FENCE;

    mOffset = (mOffset + 1) % MAX_FRAME_HISTORY;
    mFrameCounter++;

    checkFencesForCompletion();
}

} // namespace android
