// 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) {
            (void)metadata;
            // TODO(joshuaduong): CP go/oag/2170490
            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);
        },
    .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
