/*
 * Copyright 2017 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.
 */
#undef LOG_TAG
#define LOG_TAG "SurfaceTracing"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include "SurfaceTracing.h"
#include <SurfaceFlinger.h>

#include <android-base/file.h>
#include <android-base/stringprintf.h>
#include <log/log.h>
#include <utils/SystemClock.h>
#include <utils/Trace.h>

namespace android {

SurfaceTracing::SurfaceTracing(SurfaceFlinger& flinger)
      : mFlinger(flinger), mSfLock(flinger.mDrawingStateLock) {}

void SurfaceTracing::mainLoop() {
    addFirstEntry();
    bool enabled = true;
    while (enabled) {
        LayersTraceProto entry = traceWhenNotified();
        enabled = addTraceToBuffer(entry);
    }
}

void SurfaceTracing::addFirstEntry() {
    LayersTraceProto entry;
    {
        std::scoped_lock lock(mSfLock);
        entry = traceLayersLocked("tracing.enable");
    }
    addTraceToBuffer(entry);
}

LayersTraceProto SurfaceTracing::traceWhenNotified() {
    std::unique_lock<std::mutex> lock(mSfLock);
    mCanStartTrace.wait(lock);
    android::base::ScopedLockAssertion assumeLock(mSfLock);
    LayersTraceProto entry = traceLayersLocked(mWhere);
    lock.unlock();
    return entry;
}

bool SurfaceTracing::addTraceToBuffer(LayersTraceProto& entry) {
    std::scoped_lock lock(mTraceLock);
    mBuffer.emplace(std::move(entry));
    if (mWriteToFile) {
        writeProtoFileLocked();
        mWriteToFile = false;
    }
    return mEnabled;
}

void SurfaceTracing::notify(long compositionTime, const char* where) {
    std::scoped_lock lock(mSfLock);
    mCompositionTime = compositionTime;
    mWhere = where;
    mCanStartTrace.notify_one();
}

void SurfaceTracing::writeToFileAsync() {
    std::scoped_lock lock(mTraceLock);
    mWriteToFile = true;
    mCanStartTrace.notify_one();
}

void SurfaceTracing::LayersTraceBuffer::reset(size_t newSize) {
    // use the swap trick to make sure memory is released
    std::queue<LayersTraceProto>().swap(mStorage);
    mSizeInBytes = newSize;
    mUsedInBytes = 0U;
}

void SurfaceTracing::LayersTraceBuffer::emplace(LayersTraceProto&& proto) {
    auto protoSize = proto.ByteSize();
    while (mUsedInBytes + protoSize > mSizeInBytes) {
        if (mStorage.empty()) {
            return;
        }
        mUsedInBytes -= mStorage.front().ByteSize();
        mStorage.pop();
    }
    mUsedInBytes += protoSize;
    mStorage.emplace();
    mStorage.back().Swap(&proto);
}

void SurfaceTracing::LayersTraceBuffer::flush(LayersTraceFileProto* fileProto) {
    fileProto->mutable_entry()->Reserve(mStorage.size());

    while (!mStorage.empty()) {
        auto entry = fileProto->add_entry();
        entry->Swap(&mStorage.front());
        mStorage.pop();
    }
}

void SurfaceTracing::enable() {
    std::scoped_lock lock(mTraceLock);

    if (mEnabled) {
        return;
    }
    mBuffer.reset(mBufferSize);
    mEnabled = true;
    mThread = std::thread(&SurfaceTracing::mainLoop, this);
}

status_t SurfaceTracing::writeToFile() {
    mThread.join();
    return mLastErr;
}

bool SurfaceTracing::disable() {
    std::scoped_lock lock(mTraceLock);

    if (!mEnabled) {
        return false;
    }

    mEnabled = false;
    mWriteToFile = true;
    mCanStartTrace.notify_all();
    return true;
}

bool SurfaceTracing::isEnabled() const {
    std::scoped_lock lock(mTraceLock);
    return mEnabled;
}

void SurfaceTracing::setBufferSize(size_t bufferSizeInByte) {
    std::scoped_lock lock(mTraceLock);
    mBufferSize = bufferSizeInByte;
    mBuffer.setSize(bufferSizeInByte);
}

void SurfaceTracing::setTraceFlags(uint32_t flags) {
    std::scoped_lock lock(mSfLock);
    mTraceFlags = flags;
}

LayersTraceProto SurfaceTracing::traceLayersLocked(const char* where) {
    ATRACE_CALL();

    LayersTraceProto entry;
    entry.set_elapsed_realtime_nanos(mCompositionTime);
    entry.set_where(where);
    LayersProto layers(mFlinger.dumpDrawingStateProto(mTraceFlags));
    entry.mutable_layers()->Swap(&layers);

    return entry;
}

void SurfaceTracing::writeProtoFileLocked() {
    ATRACE_CALL();

    LayersTraceFileProto fileProto;
    std::string output;

    fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
                               LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
    mBuffer.flush(&fileProto);
    mBuffer.reset(mBufferSize);

    if (!fileProto.SerializeToString(&output)) {
        ALOGE("Could not save the proto file! Permission denied");
        mLastErr = PERMISSION_DENIED;
    }
    if (!android::base::WriteStringToFile(output, kDefaultFileName, S_IRWXU | S_IRGRP, getuid(),
                                          getgid(), true)) {
        ALOGE("Could not save the proto file! There are missing fields");
        mLastErr = PERMISSION_DENIED;
    }

    mLastErr = NO_ERROR;
}

void SurfaceTracing::dump(std::string& result) const {
    std::scoped_lock lock(mTraceLock);
    base::StringAppendF(&result, "Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
    base::StringAppendF(&result, "  number of entries: %zu (%.2fMB / %.2fMB)\n",
                        mBuffer.frameCount(), float(mBuffer.used()) / float(1_MB),
                        float(mBuffer.size()) / float(1_MB));
}

} // namespace android
