// Copyright 2017 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. #pragma once #include #include #include #include #include #include #include #include #include "Common/CommonTypes.h" #include "Common/Event.h" #include "Common/Flag.h" namespace VideoCommon { class AsyncShaderCompiler { public: class WorkItem { public: virtual ~WorkItem() = default; virtual bool Compile() = 0; virtual void Retrieve() = 0; }; using WorkItemPtr = std::unique_ptr; AsyncShaderCompiler(); virtual ~AsyncShaderCompiler(); template static WorkItemPtr CreateWorkItem(Params... params) { return std::unique_ptr(new T(params...)); } void QueueWorkItem(WorkItemPtr item); void RetrieveWorkItems(); bool HasPendingWork(); // Simpler version without progress updates. void WaitUntilCompletion(); // Calls progress_callback periodically, with completed_items, and total_items. void WaitUntilCompletion(const std::function& progress_callback); // Needed because of calling virtual methods in shutdown procedure. void StartWorkerThreads(u32 num_worker_threads); bool HasWorkerThreads() const; void StopWorkerThreads(); protected: virtual bool WorkerThreadInitMainThread(void** param); virtual bool WorkerThreadInitWorkerThread(void* param); virtual void WorkerThreadExit(void* param); private: void WorkerThreadEntryPoint(void* param); void WorkerThreadRun(); Common::Flag m_exit_flag; Common::Event m_init_event; std::vector m_worker_threads; std::atomic_bool m_worker_thread_start_result{false}; std::deque m_pending_work; std::mutex m_pending_work_lock; std::condition_variable m_worker_thread_wake; std::atomic_size_t m_busy_workers{0}; std::deque m_completed_work; std::mutex m_completed_work_lock; }; } // namespace VideoCommon