/*
 * 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.
 */

#pragma once

#if GFXSTREAM_ENABLE_HOST_GLES
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include "gl/EmulatedEglFenceSync.h"
#endif

#include <functional>
#include <future>
#include <string>
#include <type_traits>

#include "aemu/base/HealthMonitor.h"
#include "aemu/base/Optional.h"
#include "aemu/base/synchronization/ConditionVariable.h"
#include "aemu/base/synchronization/Lock.h"
#include "aemu/base/synchronization/MessageChannel.h"
#include "aemu/base/threads/Thread.h"
#include "aemu/base/threads/ThreadPool.h"
#include "render-utils/virtio_gpu_ops.h"
#include "vulkan/VkDecoderGlobalState.h"

namespace gfxstream {

using emugl::HealthMonitor;
using emugl::HealthWatchdog;

// SyncThread///////////////////////////////////////////////////////////////////
// The purpose of SyncThread is to track sync device timelines and give out +
// signal FD's that correspond to the completion of host-side GL fence commands.

struct RenderThreadInfo;
class SyncThread : public android::base::Thread {
   public:
    // - constructor: start up the sync worker threads for a given context.
    // The initialization of the sync threads is nonblocking.
    // - Triggers a |SyncThreadCmd| with op code |SYNC_THREAD_EGL_INIT|
    SyncThread(bool hasGl, HealthMonitor<>* healthMonitor);
    ~SyncThread();

    // |triggerWaitVk|: async wait with a given VkFence object.
    // The |vkFence| argument is a *boxed* host Vulkan handle of the fence.
    //
    // We call vkWaitForFences() on host Vulkan device to wait for the fence.
    // After wait is over, the timeline will be incremented,
    // which should signal the guest-side fence FD / Zircon eventpair.
    // This method is how the goldfish sync virtual device
    // knows when to increment timelines / signal native fence FD's.
    void triggerWaitVk(VkFence vkFence, uint64_t timeline);

#if GFXSTREAM_ENABLE_HOST_GLES
    // |triggerWait|: async wait with a given EmulatedEglFenceSync object.
    // We use the wait() method to do a eglClientWaitSyncKHR.
    // After wait is over, the timeline will be incremented,
    // which should signal the guest-side fence FD.
    // This method is how the goldfish sync virtual device
    // knows when to increment timelines / signal native fence FD's.
    void triggerWait(gl::EmulatedEglFenceSync* fenceSync, uint64_t timeline);

    // for use with the virtio-gpu path; is meant to have a current context
    // while waiting.
    void triggerBlockedWaitNoTimeline(gl::EmulatedEglFenceSync* fenceSync);

    // For use with virtio-gpu and async fence completion callback. This is async like triggerWait,
    // but takes a fence completion callback instead of incrementing some timeline directly.
    void triggerWaitWithCompletionCallback(gl::EmulatedEglFenceSync* fenceSync,
                                           FenceCompletionCallback);

    // |initSyncContext| creates an EGL context expressly for calling
    // eglClientWaitSyncKHR in the processing caused by |triggerWait|.
    // This is used by the constructor only. It is non-blocking.
    // - Triggers a |SyncThreadCmd| with op code |SYNC_THREAD_EGL_INIT|
    void initSyncEGLContext();

    void doSyncWait(gl::EmulatedEglFenceSync* fenceSync, std::function<void()> onComplete);
#endif

    // This increments the timeline after the QSRI completes.
    void triggerWaitVkQsri(VkImage vkImage, uint64_t timeline);

    void triggerWaitVkWithCompletionCallback(VkFence fenceHandle, FenceCompletionCallback);
    void triggerWaitVkQsriWithCompletionCallback(VkImage image, FenceCompletionCallback);
    void triggerGeneral(FenceCompletionCallback, std::string description);

    // |cleanup|: for use with destructors and other cleanup functions.
    // it destroys the sync context and exits the sync thread.
    // This is blocking; after this function returns, we're sure
    // the sync thread is gone.
    // - Triggers a |SyncThreadCmd| with op code |SYNC_THREAD_EXIT|
    void cleanup();

    // Initialize the global sync thread.
    static void initialize(bool hasGl, HealthMonitor<>* healthMonitor);

    // Obtains the global sync thread.
    static SyncThread* get();

    // Destroys and cleanup the global sync thread.
    static void destroy();

   private:
    using WorkerId = android::base::ThreadPoolWorkerId;
    struct Command {
        std::packaged_task<int(WorkerId)> mTask;
        std::string mDescription;
    };
    using ThreadPool = android::base::ThreadPool<Command>;

    // Thread function.
    // It keeps the workers runner until |mExiting| is set.
    virtual intptr_t main() override final;

    // These two functions are used to communicate with the sync thread from another thread:
    // - |sendAndWaitForResult| issues |job| to the sync thread, and blocks until it receives the
    // result of the job.
    // - |sendAsync| issues |job| to the sync thread and does not wait for the result, returning
    // immediately after.
    int sendAndWaitForResult(std::function<int(WorkerId)> job, std::string description);
    void sendAsync(std::function<void(WorkerId)> job, std::string description);

    // |doSyncThreadCmd| execute the actual task. These run on the sync thread.
    void doSyncThreadCmd(Command&& command, ThreadPool::WorkerId);

    static int doSyncWaitVk(VkFence, std::function<void()> onComplete);

    // EGL objects / object handles specific to
    // a sync thread.
    static const uint32_t kNumWorkerThreads = 4u;

#if GFXSTREAM_ENABLE_HOST_GLES
    EGLDisplay mDisplay = EGL_NO_DISPLAY;
    EGLSurface mSurface[kNumWorkerThreads];
    EGLContext mContext[kNumWorkerThreads];
#endif

    bool mExiting = false;
    android::base::Lock mLock;
    android::base::ConditionVariable mCv;
    ThreadPool mWorkerThreadPool;
    bool mHasGl;

    HealthMonitor<>* mHealthMonitor;
};

}  // namespace gfxstream
