mirror of
https://github.com/dolphin-emu/dolphin
synced 2024-11-04 20:43:44 -05:00
89 lines
2.4 KiB
C++
89 lines
2.4 KiB
C++
// Copyright 2017 Dolphin Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#include <atomic>
|
|
#include <condition_variable>
|
|
#include <deque>
|
|
#include <functional>
|
|
#include <map>
|
|
#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::make_unique<T>(std::forward<Params>(params)...);
|
|
}
|
|
|
|
// Queues a new work item to the compiler threads. The lower the priority, the sooner
|
|
// this work item will be compiled, relative to the other work items.
|
|
void QueueWorkItem(WorkItemPtr item, u32 priority);
|
|
void RetrieveWorkItems();
|
|
bool HasPendingWork();
|
|
bool HasCompletedWork();
|
|
|
|
// Calls progress_callback periodically, with completed_items, and total_items.
|
|
// Returns false if interrupted.
|
|
bool 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};
|
|
|
|
// A multimap is used to store the work items. We can't use a priority_queue here, because
|
|
// there's no way to obtain a non-const reference, which we need for the unique_ptr.
|
|
std::multimap<u32, 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
|