2017-06-18 22:17:18 -06:00
|
|
|
// Copyright 2017 Dolphin Emulator Project
|
|
|
|
// Licensed under GPLv2+
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
#include <condition_variable>
|
|
|
|
#include <deque>
|
|
|
|
#include <functional>
|
|
|
|
#include <memory>
|
|
|
|
#include <mutex>
|
|
|
|
#include <thread>
|
2017-09-02 11:49:07 -06:00
|
|
|
#include <utility>
|
2017-06-18 22:17:18 -06:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#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<WorkItem>;
|
|
|
|
|
|
|
|
AsyncShaderCompiler();
|
|
|
|
virtual ~AsyncShaderCompiler();
|
|
|
|
|
|
|
|
template <typename T, typename... Params>
|
2017-09-02 11:49:07 -06:00
|
|
|
static WorkItemPtr CreateWorkItem(Params&&... params)
|
2017-06-18 22:17:18 -06:00
|
|
|
{
|
2017-09-02 12:07:57 -06:00
|
|
|
return std::make_unique<T>(std::forward<Params>(params)...);
|
2017-06-18 22:17:18 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
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<void(size_t, size_t)>& progress_callback);
|
|
|
|
|
|
|
|
// Needed because of calling virtual methods in shutdown procedure.
|
2017-07-26 21:15:38 -06:00
|
|
|
bool StartWorkerThreads(u32 num_worker_threads);
|
|
|
|
bool ResizeWorkerThreads(u32 num_worker_threads);
|
2017-06-18 22:17:18 -06:00
|
|
|
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<std::thread> m_worker_threads;
|
|
|
|
std::atomic_bool m_worker_thread_start_result{false};
|
|
|
|
|
|
|
|
std::deque<WorkItemPtr> 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<WorkItemPtr> m_completed_work;
|
|
|
|
std::mutex m_completed_work_lock;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace VideoCommon
|