dolphin/Source/Core/VideoCommon/AsyncShaderCompiler.h
Lioncash 62615c601e AsyncShaderCompiler: Forward arguments to the specified type's constructor in CreateWorkItem()
As this just hands off the arguments to another type's constructor,
perfect forwarding should be used here to preserve any potential move semantics.
2017-09-02 14:06:48 -04:00

86 lines
2.1 KiB
C++

// 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>
#include <utility>
#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>
static WorkItemPtr CreateWorkItem(Params&&... params)
{
return std::unique_ptr<WorkItem>(new T(std::forward<Params>(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<void(size_t, size_t)>& progress_callback);
// Needed because of calling virtual methods in shutdown procedure.
bool StartWorkerThreads(u32 num_worker_threads);
bool ResizeWorkerThreads(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<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