// Copyright (C) 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.
#include "RendererImpl.h"

#include <assert.h>

#include <algorithm>
#include <utility>
#include <variant>

#include "FrameBuffer.h"
#include "RenderChannelImpl.h"
#include "RenderThread.h"
#include "aemu/base/system/System.h"
#include "aemu/base/threads/WorkerThread.h"
#include "gl/EmulatedEglFenceSync.h"
#include "host-common/logging.h"
#include "snapshot/common.h"

namespace gfxstream {

// kUseSubwindowThread is used to determine whether the RenderWindow should use
// a separate thread to manage its subwindow GL/GLES context.
// For now, this feature is disabled entirely for the following
// reasons:
//
// - It must be disabled on Windows at all times, otherwise the main window
//   becomes unresponsive after a few seconds of user interaction (e.g. trying
//   to move it over the desktop). Probably due to the subtle issues around
//   input on this platform (input-queue is global, message-queue is
//   per-thread). Also, this messes considerably the display of the
//   main window when running the executable under Wine.
//
// - On Linux/XGL and OSX/Cocoa, this used to be necessary to avoid corruption
//   issues with the GL state of the main window when using the SDL UI.
//   After the switch to Qt, this is no longer necessary and may actually cause
//   undesired interactions between the UI thread and the RenderWindow thread:
//   for example, in a multi-monitor setup the context might be recreated when
//   dragging the window between monitors, triggering a Qt-specific callback
//   in the context of RenderWindow thread, which will become blocked on the UI
//   thread, which may in turn be blocked on something else.
static const bool kUseSubwindowThread = false;

// This object manages the cleanup of guest process resources when the process
// exits. It runs the cleanup in a separate thread to never block the main
// render thread for a low-priority task.
class RendererImpl::ProcessCleanupThread {
public:
    ProcessCleanupThread()
        : mCleanupWorker([](Cmd cmd) {
            using android::base::WorkerProcessingResult;
            struct {
                WorkerProcessingResult operator()(CleanProcessResources resources) {
                    FrameBuffer::getFB()->cleanupProcGLObjects(resources.puid);
                    // resources.resource are destroyed automatically when going out of the scope.
                    return WorkerProcessingResult::Continue;
                }
                WorkerProcessingResult operator()(Exit) {
                    return WorkerProcessingResult::Stop;
                }
            } visitor;
            return std::visit(visitor, std::move(cmd));
          }) {
        mCleanupWorker.start();
    }

    ~ProcessCleanupThread() {
        mCleanupWorker.enqueue(Exit{});
    }

    void cleanup(uint64_t processId, std::unique_ptr<ProcessResources> resource) {
        mCleanupWorker.enqueue(CleanProcessResources{
            .puid = processId,
            .resource = std::move(resource),
        });
    }

    void stop() {
        mCleanupWorker.enqueue(Exit{});
    }

    void waitForCleanup() {
        mCleanupWorker.waitQueuedItems();
    }

private:
    struct CleanProcessResources {
        uint64_t puid;
        std::unique_ptr<ProcessResources> resource;
    };
    struct Exit {};
    using Cmd = std::variant<CleanProcessResources, Exit>;
    DISALLOW_COPY_AND_ASSIGN(ProcessCleanupThread);

    android::base::WorkerThread<Cmd> mCleanupWorker;
};

RendererImpl::RendererImpl() {
    mCleanupThread.reset(new ProcessCleanupThread());
}

RendererImpl::~RendererImpl() {
    stop(true);
    // We can't finish until the loader render thread has
    // completed else can get a crash at the end of the destructor.
    if (mLoaderRenderThread) {
        mLoaderRenderThread->wait();
    }
    mRenderWindow.reset();
}

bool RendererImpl::initialize(int width, int height, bool useSubWindow, bool egl2egl) {
    if (android::base::getEnvironmentVariable("ANDROID_EMUGL_VERBOSE") == "1") {
        // base_enable_verbose_logs();
    }

    if (mRenderWindow) {
        return false;
    }

    std::unique_ptr<RenderWindow> renderWindow(new RenderWindow(
            width, height, kUseSubwindowThread, useSubWindow, egl2egl));
    if (!renderWindow) {
        ERR("Could not create rendering window class\n");
        GL_LOG("Could not create rendering window class");
        return false;
    }
    if (!renderWindow->isValid()) {
        ERR("Could not initialize emulated framebuffer\n");
        return false;
    }

    mRenderWindow = std::move(renderWindow);
    GL_LOG("OpenGL renderer initialized successfully");

    // This render thread won't do anything but will only preload resources
    // for the real threads to start faster.
    mLoaderRenderThread.reset(new RenderThread(nullptr));
    mLoaderRenderThread->start();

    return true;
}

void RendererImpl::stop(bool wait) {
    android::base::AutoLock lock(mChannelsLock);
    mStopped = true;
    auto channels = std::move(mChannels);
    lock.unlock();

    if (const auto fb = FrameBuffer::getFB()) {
        fb->setShuttingDown();
    }
    for (const auto& c : channels) {
        c->stopFromHost();
    }
    // We're stopping the renderer, so there's no need to clean up resources
    // of some pending processes: we'll destroy everything soon.
    mCleanupThread->stop();

    mStoppedChannels.insert(mStoppedChannels.end(),
                            std::make_move_iterator(channels.begin()),
                            std::make_move_iterator(channels.end()));

    if (!wait) {
        return;
    }

    // Each render channel is referenced in the corresponing pipe object, so
    // even if we clear the |channels| vector they could still be alive
    // for a while. This means we need to make sure to wait for render thread
    // exit explicitly.
    for (const auto& c : mStoppedChannels) {
        c->renderThread()->wait();
    }
    mStoppedChannels.clear();
}

void RendererImpl::finish() {
    {
        android::base::AutoLock lock(mChannelsLock);
        mRenderWindow->setPaused(true);
    }
    cleanupRenderThreads();
    {
        android::base::AutoLock lock(mChannelsLock);
        mRenderWindow->setPaused(false);
    }
}

void RendererImpl::cleanupRenderThreads() {
    android::base::AutoLock lock(mChannelsLock);
    const auto channels = std::move(mChannels);
    assert(mChannels.empty());
    lock.unlock();
    for (const auto& c : channels) {
        // Please DO NOT notify the guest about this event (DO NOT call
        // stopFromHost() ), because this is used to kill old threads when
        // loading from a snapshot, and the newly loaded guest should not
        // be notified for those behavior.
        c->stop();
    }
    for (const auto& c : channels) {
        c->renderThread()->wait();
    }
}

void RendererImpl::waitForProcessCleanup() {
    mCleanupThread->waitForCleanup();
    // Recreate it to make sure we've started from scratch and that we've
    // finished all in-progress cleanups as well.
    mCleanupThread.reset(new ProcessCleanupThread());
}

RenderChannelPtr RendererImpl::createRenderChannel(
        android::base::Stream* loadStream) {
    const auto channel = std::make_shared<RenderChannelImpl>(loadStream);
    {
        android::base::AutoLock lock(mChannelsLock);

        if (mStopped) {
            return nullptr;
        }

        // Clean up the stopped channels.
        mChannels.erase(
                std::remove_if(mChannels.begin(), mChannels.end(),
                               [](const std::shared_ptr<RenderChannelImpl>& c) {
                                   return c->renderThread()->isFinished();
                               }),
                mChannels.end());
        mChannels.emplace_back(channel);

        // Take the time to check if our loader thread is done as well.
        if (mLoaderRenderThread && mLoaderRenderThread->isFinished()) {
            mLoaderRenderThread->wait();
            mLoaderRenderThread.reset();
        }

        GL_LOG("Started new RenderThread (total %" PRIu64 ") @%p",
               static_cast<uint64_t>(mChannels.size()), channel->renderThread());
    }

    return channel;
}

void RendererImpl::addListener(FrameBufferChangeEventListener* listener) {
    mRenderWindow->addListener(listener);
}

void RendererImpl::removeListener(FrameBufferChangeEventListener* listener) {
    mRenderWindow->removeListener(listener);
}

void* RendererImpl::addressSpaceGraphicsConsumerCreate(
    struct asg_context context,
    android::base::Stream* loadStream,
    android::emulation::asg::ConsumerCallbacks callbacks,
    uint32_t contextId, uint32_t capsetId,
    std::optional<std::string> nameOpt) {
    auto thread = new RenderThread(context, loadStream, callbacks, contextId,
                                   capsetId, std::move(nameOpt));
    thread->start();
    return (void*)thread;
}

void RendererImpl::addressSpaceGraphicsConsumerDestroy(void* consumer) {
    RenderThread* thread = (RenderThread*)consumer;
    thread->wait();
    delete thread;
}

void RendererImpl::addressSpaceGraphicsConsumerPreSave(void* consumer) {
    RenderThread* thread = (RenderThread*)consumer;
    thread->pausePreSnapshot();
}

void RendererImpl::addressSpaceGraphicsConsumerSave(void* consumer, android::base::Stream* stream) {
    RenderThread* thread = (RenderThread*)consumer;
    thread->save(stream);
}

void RendererImpl::addressSpaceGraphicsConsumerPostSave(void* consumer) {
    RenderThread* thread = (RenderThread*)consumer;
    thread->resume();
}

void RendererImpl::addressSpaceGraphicsConsumerRegisterPostLoadRenderThread(void* consumer) {
    RenderThread* thread = (RenderThread*)consumer;
    mAdditionalPostLoadRenderThreads.push_back(thread);
}

void RendererImpl::pauseAllPreSave() {
    android::base::AutoLock lock(mChannelsLock);
    if (mStopped) {
        return;
    }
    for (const auto& c : mChannels) {
        c->renderThread()->pausePreSnapshot();
    }
    lock.unlock();
    waitForProcessCleanup();
}

void RendererImpl::resumeAll() {
    {
        android::base::AutoLock lock(mChannelsLock);
        if (mStopped) {
            return;
        }
        for (const auto& c : mChannels) {
            c->renderThread()->resume();
        }

        for (const auto t: mAdditionalPostLoadRenderThreads) {
            t->resume();
        }
        mAdditionalPostLoadRenderThreads.clear();
    }

    repaintOpenGLDisplay();
}

void RendererImpl::save(android::base::Stream* stream,
                        const android::snapshot::ITextureSaverPtr& textureSaver) {
    stream->putByte(mStopped);
    if (mStopped) {
        return;
    }
    auto fb = FrameBuffer::getFB();
    assert(fb);
    fb->onSave(stream, textureSaver);
}

bool RendererImpl::load(android::base::Stream* stream,
                        const android::snapshot::ITextureLoaderPtr& textureLoader) {

#ifdef SNAPSHOT_PROFILE
    android::base::System::Duration startTime =
            android::base::System::get()->getUnixTimeUs();
#endif
    waitForProcessCleanup();
#ifdef SNAPSHOT_PROFILE
    printf("Previous session cleanup time: %lld ms\n",
           (long long)(android::base::System::get()
                               ->getUnixTimeUs() -
                       startTime) /
                   1000);
#endif

    mStopped = stream->getByte();
    if (mStopped) {
        return true;
    }
    auto fb = FrameBuffer::getFB();
    assert(fb);

    bool res = true;

    res = fb->onLoad(stream, textureLoader);
    gl::EmulatedEglFenceSync::onLoad(stream);

    return res;
}

void RendererImpl::fillGLESUsages(android_studio::EmulatorGLESUsages* usages) {
    auto fb = FrameBuffer::getFB();
    if (fb) fb->fillGLESUsages(usages);
}

int RendererImpl::getScreenshot(unsigned int nChannels, unsigned int* width, unsigned int* height,
                                uint8_t* pixels, size_t* cPixels, int displayId = 0,
                                int desiredWidth = 0, int desiredHeight = 0,
                                int desiredRotation = 0, Rect rect = {{0, 0}, {0, 0}}) {
    auto fb = FrameBuffer::getFB();
    if (fb) {
        return fb->getScreenshot(nChannels, width, height, pixels, cPixels,
                                 displayId, desiredWidth, desiredHeight,
                                 desiredRotation, rect);
    }
    *cPixels = 0;
    return -1;
}

void RendererImpl::setMultiDisplay(uint32_t id,
                                   int32_t x,
                                   int32_t y,
                                   uint32_t w,
                                   uint32_t h,
                                   uint32_t dpi,
                                   bool add) {
    auto fb = FrameBuffer::getFB();
    if (fb) {
        if (add) {
            fb->createDisplay(&id);
            fb->setDisplayPose(id, x, y, w, h, dpi);
        } else {
            fb->destroyDisplay(id);
        }
    }
}

void RendererImpl::setMultiDisplayColorBuffer(uint32_t id, uint32_t cb) {
    auto fb = FrameBuffer::getFB();
    if (fb) {
        fb->setDisplayColorBuffer(id, cb);
    }
}

RendererImpl::HardwareStrings RendererImpl::getHardwareStrings() {
    assert(mRenderWindow);

    const char* vendor = nullptr;
    const char* renderer = nullptr;
    const char* version = nullptr;
    if (!mRenderWindow->getHardwareStrings(&vendor, &renderer, &version)) {
        return {};
    }
    HardwareStrings res;
    res.vendor = vendor ? vendor : "";
    res.renderer = renderer ? renderer : "";
    res.version = version ? version : "";
    return res;
}

void RendererImpl::setPostCallback(RendererImpl::OnPostCallback onPost,
                                   void* context,
                                   bool useBgraReadback,
                                   uint32_t displayId) {
    assert(mRenderWindow);
    mRenderWindow->setPostCallback(onPost, context, displayId, useBgraReadback);
}

bool RendererImpl::asyncReadbackSupported() {
    assert(mRenderWindow);
    return mRenderWindow->asyncReadbackSupported();
}

RendererImpl::ReadPixelsCallback
RendererImpl::getReadPixelsCallback() {
    assert(mRenderWindow);
    return mRenderWindow->getReadPixelsCallback();
}

RendererImpl::FlushReadPixelPipeline
RendererImpl::getFlushReadPixelPipeline() {
    assert(mRenderWindow);
    return mRenderWindow->getFlushReadPixelPipeline();
}

bool RendererImpl::showOpenGLSubwindow(FBNativeWindowType window,
                                       int wx,
                                       int wy,
                                       int ww,
                                       int wh,
                                       int fbw,
                                       int fbh,
                                       float dpr,
                                       float zRot,
                                       bool deleteExisting,
                                       bool hideWindow) {
    assert(mRenderWindow);
    return mRenderWindow->setupSubWindow(window, wx, wy, ww, wh, fbw, fbh, dpr,
                                         zRot, deleteExisting, hideWindow);
}

bool RendererImpl::destroyOpenGLSubwindow() {
    assert(mRenderWindow);
    return mRenderWindow->removeSubWindow();
}

void RendererImpl::setOpenGLDisplayRotation(float zRot) {
    assert(mRenderWindow);
    mRenderWindow->setRotation(zRot);
}

void RendererImpl::setOpenGLDisplayTranslation(float px, float py) {
    assert(mRenderWindow);
    mRenderWindow->setTranslation(px, py);
}

void RendererImpl::repaintOpenGLDisplay() {
    assert(mRenderWindow);
    mRenderWindow->repaint();
}

bool RendererImpl::hasGuestPostedAFrame() {
    if (mRenderWindow) {
        return mRenderWindow->hasGuestPostedAFrame();
    }
    return false;
}

void RendererImpl::resetGuestPostedAFrame() {
    if (mRenderWindow) {
        mRenderWindow->resetGuestPostedAFrame();
    }
}

void RendererImpl::setScreenMask(int width, int height, const unsigned char* rgbaData) {
    assert(mRenderWindow);
    mRenderWindow->setScreenMask(width, height, rgbaData);
}

void RendererImpl::onGuestGraphicsProcessCreate(uint64_t puid) {
    FrameBuffer::getFB()->createGraphicsProcessResources(puid);
}

void RendererImpl::cleanupProcGLObjects(uint64_t puid) {
    std::unique_ptr<ProcessResources> resource =
        FrameBuffer::getFB()->removeGraphicsProcessResources(puid);
    mCleanupThread->cleanup(puid, std::move(resource));
}

static struct AndroidVirtioGpuOps sVirtioGpuOps = {
    .create_buffer_with_handle =
        [](uint64_t size, uint32_t handle) {
            FrameBuffer::getFB()->createBufferWithHandle(size, handle);
        },
    .create_color_buffer_with_handle =
        [](uint32_t width, uint32_t height, uint32_t format, uint32_t fwkFormat, uint32_t handle) {
            FrameBuffer::getFB()->createColorBufferWithHandle(width, height, (GLenum)format,
                                                              (FrameworkFormat)fwkFormat, handle);
        },
    .open_color_buffer = [](uint32_t handle) { FrameBuffer::getFB()->openColorBuffer(handle); },
    .close_buffer = [](uint32_t handle) { FrameBuffer::getFB()->closeBuffer(handle); },
    .close_color_buffer = [](uint32_t handle) { FrameBuffer::getFB()->closeColorBuffer(handle); },
    .update_buffer =
        [](uint32_t handle, uint64_t offset, uint64_t size, void* bytes) {
            FrameBuffer::getFB()->updateBuffer(handle, offset, size, bytes);
        },
    .update_color_buffer =
        [](uint32_t handle, int x, int y, int width, int height, uint32_t format, uint32_t type,
           void* pixels) {
            FrameBuffer::getFB()->updateColorBuffer(handle, x, y, width, height, format, type,
                                                    pixels);
        },
    .read_buffer =
        [](uint32_t handle, uint64_t offset, uint64_t size, void* bytes) {
            FrameBuffer::getFB()->readBuffer(handle, offset, size, bytes);
        },
    .read_color_buffer =
        [](uint32_t handle, int x, int y, int width, int height, uint32_t format, uint32_t type,
           void* pixels) {
            FrameBuffer::getFB()->readColorBuffer(handle, x, y, width, height, format, type,
                                                  pixels);
        },
    .read_color_buffer_yuv =
        [](uint32_t handle, int x, int y, int width, int height, void* pixels,
           uint32_t pixels_size) {
            FrameBuffer::getFB()->readColorBufferYUV(handle, x, y, width, height, pixels,
                                                     pixels_size);
        },
    .post_color_buffer = [](uint32_t handle) { FrameBuffer::getFB()->post(handle); },
    .async_post_color_buffer =
        [](uint32_t handle, CpuCompletionCallback cb) {
            FrameBuffer::getFB()->postWithCallback(handle, cb);
        },
    .repost = []() { FrameBuffer::getFB()->repost(); },
    .create_yuv_textures =
        [](uint32_t type, uint32_t count, int width, int height, uint32_t* output) {
            FrameBuffer::getFB()->createYUVTextures(type, count, width, height, output);
        },
    .destroy_yuv_textures =
        [](uint32_t type, uint32_t count, uint32_t* textures) {
            FrameBuffer::getFB()->destroyYUVTextures(type, count, textures);
        },
    .update_yuv_textures =
        [](uint32_t type, uint32_t* textures, void* privData, void* func) {
            FrameBuffer::getFB()->updateYUVTextures(type, textures, privData, func);
        },
    .swap_textures_and_update_color_buffer =
        [](uint32_t colorbufferhandle, int x, int y, int width, int height, uint32_t format,
           uint32_t type, uint32_t texture_type, uint32_t* textures, void* metadata) {
            FrameBuffer::getFB()->swapTexturesAndUpdateColorBuffer(
                colorbufferhandle, x, y, width, height, format, type, texture_type, textures);
        },
    .get_last_posted_color_buffer =
        []() { return FrameBuffer::getFB()->getLastPostedColorBuffer(); },
    .bind_color_buffer_to_texture =
        [](uint32_t handle) { FrameBuffer::getFB()->bindColorBufferToTexture2(handle); },
    .get_global_egl_context = []() { return FrameBuffer::getFB()->getGlobalEGLContext(); },
    .wait_for_gpu = [](uint64_t eglsync) { FrameBuffer::getFB()->waitForGpu(eglsync); },
    .wait_for_gpu_vulkan =
        [](uint64_t device, uint64_t fence) {
            FrameBuffer::getFB()->waitForGpuVulkan(device, fence);
        },
    .set_guest_managed_color_buffer_lifetime =
        [](bool guestManaged) {
            FrameBuffer::getFB()->setGuestManagedColorBufferLifetime(guestManaged);
        },
    .async_wait_for_gpu_with_cb =
        [](uint64_t eglsync, FenceCompletionCallback cb) {
            FrameBuffer::getFB()->asyncWaitForGpuWithCb(eglsync, cb);
        },
    .async_wait_for_gpu_vulkan_with_cb =
        [](uint64_t device, uint64_t fence, FenceCompletionCallback cb) {
            FrameBuffer::getFB()->asyncWaitForGpuVulkanWithCb(device, fence, cb);
        },
    .async_wait_for_gpu_vulkan_qsri_with_cb =
        [](uint64_t image, FenceCompletionCallback cb) {
            FrameBuffer::getFB()->asyncWaitForGpuVulkanQsriWithCb(image, cb);
        },
    .wait_for_gpu_vulkan_qsri =
        [](uint64_t image) { FrameBuffer::getFB()->waitForGpuVulkanQsri(image); },
    .update_color_buffer_from_framework_format =
        [](uint32_t handle, int x, int y, int width, int height, uint32_t fwkFormat,
           uint32_t format, uint32_t type, void* pixels, void* pMetadata) {
            FrameBuffer::getFB()->updateColorBufferFromFrameworkFormat(
                handle, x, y, width, height, (FrameworkFormat)fwkFormat, format, type, pixels,
                pMetadata);
        },
    .platform_import_resource =
        [](uint32_t handle, uint32_t info, void* resource) {
            return FrameBuffer::getFB()->platformImportResource(handle, info, resource);
        },
    .platform_resource_info =
        [](uint32_t handle, int32_t* width, int32_t* height, int32_t* internal_format) {
            return FrameBuffer::getFB()->getColorBufferInfo(handle, width, height, internal_format);
        },
    .platform_create_shared_egl_context =
        []() { return FrameBuffer::getFB()->platformCreateSharedEglContext(); },
    .platform_destroy_shared_egl_context =
        [](void* context) {
            return FrameBuffer::getFB()->platformDestroySharedEglContext(context);
        },
};

struct AndroidVirtioGpuOps* RendererImpl::getVirtioGpuOps() {
    return &sVirtioGpuOps;
}

void RendererImpl::snapshotOperationCallback(int op, int stage) {
    using namespace android::snapshot;
    switch (op) {
        case SNAPSHOTTER_OPERATION_LOAD:
            if (stage == SNAPSHOTTER_STAGE_START) {
#ifdef SNAPSHOT_PROFILE
             android::base::System::Duration startTime =
                     android::base::System::get()->getUnixTimeUs();
#endif
                mRenderWindow->setPaused(true);
                cleanupRenderThreads();
#ifdef SNAPSHOT_PROFILE
                printf("Previous session suspend time: %lld ms\n",
                       (long long)(android::base::System::get()
                                           ->getUnixTimeUs() -
                                   startTime) /
                               1000);
#endif
            }
            if (stage == SNAPSHOTTER_STAGE_END) {
                mRenderWindow->setPaused(false);
            }
            break;
        default:
            break;
    }
}

void RendererImpl::setVsyncHz(int vsyncHz) {
    if (mRenderWindow) {
        mRenderWindow->setVsyncHz(vsyncHz);
    }
}

void RendererImpl::setDisplayConfigs(int configId, int w, int h,
                                     int dpiX, int dpiY) {
    if (mRenderWindow) {
        mRenderWindow->setDisplayConfigs(configId, w, h, dpiX, dpiY);
    }
}

void RendererImpl::setDisplayActiveConfig(int configId) {
    if (mRenderWindow) {
        mRenderWindow->setDisplayActiveConfig(configId);
    }
}

const void* RendererImpl::getEglDispatch() {
    return FrameBuffer::getFB()->getEglDispatch();
}

const void* RendererImpl::getGles2Dispatch() {
    return FrameBuffer::getFB()->getGles2Dispatch();
}

}  // namespace gfxstream
