// Copyright 2023 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 expresso or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "Buffer.h"

#if GFXSTREAM_ENABLE_HOST_GLES
#include "gl/EmulationGl.h"
#endif

#include "vulkan/BufferVk.h"
#include "vulkan/VkCommonOperations.h"

namespace gfxstream {

using android::base::ManagedDescriptor;
using emugl::ABORT_REASON_OTHER;
using emugl::FatalError;

Buffer::Buffer(HandleType handle, uint64_t size) : mHandle(handle), mSize(size) {}

/*static*/
std::shared_ptr<Buffer> Buffer::create(gl::EmulationGl* emulationGl, vk::VkEmulation* emulationVk,
                                       uint64_t size, HandleType handle) {
    std::shared_ptr<Buffer> buffer(new Buffer(handle, size));

#if GFXSTREAM_ENABLE_HOST_GLES
    if (emulationGl) {
        buffer->mBufferGl = emulationGl->createBuffer(size, handle);
        if (!buffer->mBufferGl) {
            ERR("Failed to initialize BufferGl.");
            return nullptr;
        }
    }
#endif

    if (emulationVk && emulationVk->live) {
        const bool vulkanOnly = emulationGl == nullptr;

        buffer->mBufferVk = vk::BufferVk::create(handle, size, vulkanOnly);
        if (!buffer->mBufferVk) {
            ERR("Failed to initialize BufferVk.");
            return nullptr;
        }

        if (!vulkanOnly) {
#if GFXSTREAM_ENABLE_HOST_GLES
            if (!buffer->mBufferGl) {
                GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Missing BufferGl?";
            }
#endif
            // TODO: external memory sharing.
        }
    }

    return buffer;
}

/*static*/
std::shared_ptr<Buffer> Buffer::onLoad(gl::EmulationGl* emulationGl, vk::VkEmulation*,
                                       android::base::Stream* stream) {
    const auto handle = static_cast<HandleType>(stream->getBe32());
    const auto size = static_cast<uint64_t>(stream->getBe64());

    std::shared_ptr<Buffer> buffer(new Buffer(handle, size));

#if GFXSTREAM_ENABLE_HOST_GLES
    if (emulationGl) {
        buffer->mBufferGl = emulationGl->loadBuffer(stream);
        if (!buffer->mBufferGl) {
            ERR("Failed to load BufferGl.");
            return nullptr;
        }
    }
#endif

    buffer->mNeedRestore = true;

    return buffer;
}

void Buffer::onSave(android::base::Stream* stream) {
    stream->putBe32(mHandle);
    stream->putBe64(mSize);

#if GFXSTREAM_ENABLE_HOST_GLES
    if (mBufferGl) {
        mBufferGl->onSave(stream);
    }
#endif
}

void Buffer::restore() {}

void Buffer::readToBytes(uint64_t offset, uint64_t size, void* outBytes) {
    touch();

#if GFXSTREAM_ENABLE_HOST_GLES
    if (mBufferGl) {
        mBufferGl->read(offset, size, outBytes);
        return;
    }
#endif

    if (mBufferVk) {
        mBufferVk->readToBytes(offset, size, outBytes);
        return;
    }

    GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "No Buffer impl?";
}

bool Buffer::updateFromBytes(uint64_t offset, uint64_t size, const void* bytes) {
    touch();

#if GFXSTREAM_ENABLE_HOST_GLES
    if (mBufferGl) {
        mBufferGl->subUpdate(offset, size, bytes);
        return true;
    }
#endif

    if (mBufferVk) {
        return mBufferVk->updateFromBytes(offset, size, bytes);
    }

    GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "No Buffer impl?";
    return false;
}

}  // namespace gfxstream
