/*
 * Copyright (C) 2018 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 "ReliableSurface.h"

#include <log/log_main.h>
#include <private/android/AHardwareBufferHelpers.h>
// TODO: this should be including apex instead.
#include <vndk/window.h>

namespace android::uirenderer::renderthread {

// TODO: Re-enable after addressing more of the TODO's
// With this disabled we won't have a good up-front signal that the surface is no longer valid,
// however we can at least handle that reactively post-draw. There's just not a good mechanism
// to propagate this error back to the caller
constexpr bool DISABLE_BUFFER_PREFETCH = true;

ReliableSurface::ReliableSurface(ANativeWindow* window) : mWindow(window) {
    LOG_ALWAYS_FATAL_IF(!mWindow, "Error, unable to wrap a nullptr");
    ANativeWindow_acquire(mWindow);
}

ReliableSurface::~ReliableSurface() {
    clearReservedBuffer();
    // Clear out the interceptors for proper hygiene.
    // As a concrete example, if the underlying ANativeWindow is associated with
    // an EGLSurface that is still in use, then if we don't clear out the
    // interceptors then we walk into undefined behavior.
    ANativeWindow_setCancelBufferInterceptor(mWindow, nullptr, nullptr);
    ANativeWindow_setDequeueBufferInterceptor(mWindow, nullptr, nullptr);
    ANativeWindow_setQueueBufferInterceptor(mWindow, nullptr, nullptr);
    ANativeWindow_setPerformInterceptor(mWindow, nullptr, nullptr);
    ANativeWindow_release(mWindow);
}

void ReliableSurface::init() {
    int result = ANativeWindow_setCancelBufferInterceptor(mWindow, hook_cancelBuffer, this);
    LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set cancelBuffer interceptor: error = %d",
                        result);

    result = ANativeWindow_setDequeueBufferInterceptor(mWindow, hook_dequeueBuffer, this);
    LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set dequeueBuffer interceptor: error = %d",
                        result);

    result = ANativeWindow_setQueueBufferInterceptor(mWindow, hook_queueBuffer, this);
    LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set queueBuffer interceptor: error = %d",
                        result);

    result = ANativeWindow_setPerformInterceptor(mWindow, hook_perform, this);
    LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set perform interceptor: error = %d",
                        result);
}

int ReliableSurface::reserveNext() {
    if constexpr (DISABLE_BUFFER_PREFETCH) {
        return OK;
    }
    {
        std::lock_guard _lock{mMutex};
        if (mReservedBuffer) {
            ALOGW("reserveNext called but there was already a buffer reserved?");
            return OK;
        }
        if (mBufferQueueState != OK) {
            return UNKNOWN_ERROR;
        }
        if (mHasDequeuedBuffer) {
            return OK;
        }
    }

    // TODO: Update this to better handle when requested dimensions have changed
    // Currently the driver does this via query + perform but that's after we've already
    // reserved a buffer. Should we do that logic instead? Or should we drop
    // the backing Surface to the ground and go full manual on the IGraphicBufferProducer instead?

    int fenceFd = -1;
    ANativeWindowBuffer* buffer = nullptr;

    // Note that this calls back into our own hooked method.
    int result = ANativeWindow_dequeueBuffer(mWindow, &buffer, &fenceFd);

    {
        std::lock_guard _lock{mMutex};
        LOG_ALWAYS_FATAL_IF(mReservedBuffer, "race condition in reserveNext");
        mReservedBuffer = buffer;
        mReservedFenceFd.reset(fenceFd);
    }

    return result;
}

void ReliableSurface::clearReservedBuffer() {
    ANativeWindowBuffer* buffer = nullptr;
    int releaseFd = -1;
    {
        std::lock_guard _lock{mMutex};
        if (mReservedBuffer) {
            ALOGW("Reserved buffer %p was never used", mReservedBuffer);
            buffer = mReservedBuffer;
            releaseFd = mReservedFenceFd.release();
        }
        mReservedBuffer = nullptr;
        mReservedFenceFd.reset();
        mHasDequeuedBuffer = false;
    }
    if (buffer) {
        // Note that clearReservedBuffer may be reentrant here, so
        // mReservedBuffer must be cleared once we reach here to avoid recursing
        // forever.
        ANativeWindow_cancelBuffer(mWindow, buffer, releaseFd);
    }
}

bool ReliableSurface::isFallbackBuffer(const ANativeWindowBuffer* windowBuffer) const {
    if (!mScratchBuffer || !windowBuffer) {
        return false;
    }
    ANativeWindowBuffer* scratchBuffer =
            AHardwareBuffer_to_ANativeWindowBuffer(mScratchBuffer.get());
    return windowBuffer == scratchBuffer;
}

ANativeWindowBuffer* ReliableSurface::acquireFallbackBuffer(int error) {
    std::lock_guard _lock{mMutex};
    mBufferQueueState = error;

    if (mScratchBuffer) {
        return AHardwareBuffer_to_ANativeWindowBuffer(mScratchBuffer.get());
    }

    AHardwareBuffer_Desc desc = AHardwareBuffer_Desc{
            .usage = mUsage,
            .format = mFormat,
            .width = 1,
            .height = 1,
            .layers = 1,
            .rfu0 = 0,
            .rfu1 = 0,
    };

    AHardwareBuffer* newBuffer;
    int result = AHardwareBuffer_allocate(&desc, &newBuffer);

    if (result != NO_ERROR) {
        // Allocate failed, that sucks
        ALOGW("Failed to allocate scratch buffer, error=%d", result);
        return nullptr;
    }

    mScratchBuffer.reset(newBuffer);
    return AHardwareBuffer_to_ANativeWindowBuffer(newBuffer);
}

int ReliableSurface::hook_dequeueBuffer(ANativeWindow* window,
                                        ANativeWindow_dequeueBufferFn dequeueBuffer, void* data,
                                        ANativeWindowBuffer** buffer, int* fenceFd) {
    ReliableSurface* rs = reinterpret_cast<ReliableSurface*>(data);
    {
        std::lock_guard _lock{rs->mMutex};
        if (rs->mReservedBuffer) {
            *buffer = rs->mReservedBuffer;
            *fenceFd = rs->mReservedFenceFd.release();
            rs->mReservedBuffer = nullptr;
            return OK;
        }
    }

    int result = dequeueBuffer(window, buffer, fenceFd);
    if (result != OK) {
        ALOGW("dequeueBuffer failed, error = %d; switching to fallback", result);
        *buffer = rs->acquireFallbackBuffer(result);
        *fenceFd = -1;
        return *buffer ? OK : INVALID_OPERATION;
    } else {
        std::lock_guard _lock{rs->mMutex};
        rs->mHasDequeuedBuffer = true;
    }
    return OK;
}

int ReliableSurface::hook_cancelBuffer(ANativeWindow* window,
                                       ANativeWindow_cancelBufferFn cancelBuffer, void* data,
                                       ANativeWindowBuffer* buffer, int fenceFd) {
    ReliableSurface* rs = reinterpret_cast<ReliableSurface*>(data);
    rs->clearReservedBuffer();
    if (rs->isFallbackBuffer(buffer)) {
        if (fenceFd > 0) {
            close(fenceFd);
        }
        return OK;
    }
    return cancelBuffer(window, buffer, fenceFd);
}

int ReliableSurface::hook_queueBuffer(ANativeWindow* window,
                                      ANativeWindow_queueBufferFn queueBuffer, void* data,
                                      ANativeWindowBuffer* buffer, int fenceFd) {
    ReliableSurface* rs = reinterpret_cast<ReliableSurface*>(data);
    rs->clearReservedBuffer();

    if (rs->isFallbackBuffer(buffer)) {
        if (fenceFd > 0) {
            close(fenceFd);
        }
        return OK;
    }

    return queueBuffer(window, buffer, fenceFd);
}

int ReliableSurface::hook_perform(ANativeWindow* window, ANativeWindow_performFn perform,
                                  void* data, int operation, va_list args) {
    // Drop the reserved buffer if there is one since this (probably) mutated buffer dimensions
    // TODO: Filter to things that only affect the reserved buffer
    // TODO: Can we mutate the reserved buffer in some cases?
    ReliableSurface* rs = reinterpret_cast<ReliableSurface*>(data);
    rs->clearReservedBuffer();

    va_list argsCopy;
    va_copy(argsCopy, args);
    int result = perform(window, operation, argsCopy);

    {
        std::lock_guard _lock{rs->mMutex};

        switch (operation) {
            case ANATIVEWINDOW_PERFORM_SET_USAGE:
                rs->mUsage = va_arg(args, uint32_t);
                break;
            case ANATIVEWINDOW_PERFORM_SET_USAGE64:
                rs->mUsage = va_arg(args, uint64_t);
                break;
            case ANATIVEWINDOW_PERFORM_SET_BUFFERS_GEOMETRY:
                /* width */ va_arg(args, uint32_t);
                /* height */ va_arg(args, uint32_t);
                rs->mFormat = static_cast<AHardwareBuffer_Format>(va_arg(args, int32_t));
                break;
            case ANATIVEWINDOW_PERFORM_SET_BUFFERS_FORMAT:
                rs->mFormat = static_cast<AHardwareBuffer_Format>(va_arg(args, int32_t));
                break;
        }
    }
    return result;
}

};  // namespace android::uirenderer::renderthread
