/*
 * Copyright (C) 2012 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 LOG_TAG "Fence"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0

// We would eliminate the non-conforming zero-length array, but we can't since
// this is effectively included from the Linux kernel
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wzero-length-array"
#include <sync/sync.h>
#pragma clang diagnostic pop

#include <ui/Fence.h>
#include <unistd.h>
#include <utils/Log.h>
#include <utils/Trace.h>

namespace android {

const sp<Fence> Fence::NO_FENCE = sp<Fence>(new Fence);

Fence::Fence() :
    mFenceFd(-1) {
}

Fence::Fence(int fenceFd) :
    mFenceFd(fenceFd) {
}

Fence::~Fence() {
    if (mFenceFd != -1) {
        close(mFenceFd);
    }
}

status_t Fence::wait(int timeout) {
    ATRACE_CALL();
    if (mFenceFd == -1) {
        return NO_ERROR;
    }
    int err = sync_wait(mFenceFd, timeout);
    return err < 0 ? -errno : status_t(NO_ERROR);
}

status_t Fence::waitForever(const char* logname) {
    ATRACE_CALL();
    if (mFenceFd == -1) {
        return NO_ERROR;
    }
    int warningTimeout = 3000;
    int err = sync_wait(mFenceFd, warningTimeout);
    if (err < 0 && errno == ETIME) {
        ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd,
                warningTimeout);
        err = sync_wait(mFenceFd, TIMEOUT_NEVER);
    }
    return err < 0 ? -errno : status_t(NO_ERROR);
}

sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
        const sp<Fence>& f2) {
    ATRACE_CALL();
    int result;
    // Merge the two fences.  In the case where one of the fences is not a
    // valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so
    // that a new fence with the given name is created.
    if (f1->isValid() && f2->isValid()) {
        result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd);
    } else if (f1->isValid()) {
        result = sync_merge(name.string(), f1->mFenceFd, f1->mFenceFd);
    } else if (f2->isValid()) {
        result = sync_merge(name.string(), f2->mFenceFd, f2->mFenceFd);
    } else {
        return NO_FENCE;
    }
    if (result == -1) {
        status_t err = -errno;
        ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)",
                name.string(), f1->mFenceFd, f2->mFenceFd,
                strerror(-err), err);
        return NO_FENCE;
    }
    return sp<Fence>(new Fence(result));
}

int Fence::dup() const {
    return ::dup(mFenceFd);
}

nsecs_t Fence::getSignalTime() const {
    if (mFenceFd == -1) {
        return -1;
    }

    struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd);
    if (finfo == NULL) {
        ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd);
        return -1;
    }
    if (finfo->status != 1) {
        sync_fence_info_free(finfo);
        return INT64_MAX;
    }

    struct sync_pt_info* pinfo = NULL;
    uint64_t timestamp = 0;
    while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) {
        if (pinfo->timestamp_ns > timestamp) {
            timestamp = pinfo->timestamp_ns;
        }
    }
    sync_fence_info_free(finfo);

    return nsecs_t(timestamp);
}

size_t Fence::getFlattenedSize() const {
    return 4;
}

size_t Fence::getFdCount() const {
    return isValid() ? 1 : 0;
}

status_t Fence::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const {
    if (size < getFlattenedSize() || count < getFdCount()) {
        return NO_MEMORY;
    }
    // Cast to uint32_t since the size of a size_t can vary between 32- and
    // 64-bit processes
    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(getFdCount()));
    if (isValid()) {
        *fds++ = mFenceFd;
        count--;
    }
    return NO_ERROR;
}

status_t Fence::unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count) {
    if (mFenceFd != -1) {
        // Don't unflatten if we already have a valid fd.
        return INVALID_OPERATION;
    }

    if (size < getFlattenedSize()) {
        return NO_MEMORY;
    }

    uint32_t numFds;
    FlattenableUtils::read(buffer, size, numFds);

    if (numFds > 1) {
        return BAD_VALUE;
    }

    if (count < numFds) {
        return NO_MEMORY;
    }

    if (numFds) {
        mFenceFd = *fds++;
        count--;
    }

    return NO_ERROR;
}

} // namespace android
