attempt moving core to separate thread again
This commit is contained in:
+34
-31
@@ -1,52 +1,55 @@
|
||||
#include <Core.hpp>
|
||||
#include <EmuThread.hpp>
|
||||
#include <KaizenGui.hpp>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
EmuThread::EmuThread(double &fps, SettingsWindow &settings) noexcept : settings(settings), fps(fps) {}
|
||||
|
||||
void EmuThread::run() const noexcept {
|
||||
void EmuThread::run() noexcept {
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
if(!core.romLoaded) return;
|
||||
|
||||
auto lastSample = std::chrono::high_resolution_clock::now();
|
||||
auto avgFps = 16.667;
|
||||
auto sampledFps = 0;
|
||||
static bool oneSecondPassed = false;
|
||||
rdramCopy = core.GetMem().GetRDRAM();
|
||||
|
||||
fps = 1000.0 / avgFps;
|
||||
|
||||
const auto startFrameTime = std::chrono::high_resolution_clock::now();
|
||||
if (!core.pause) {
|
||||
core.Run(settings.getVolumeL(), settings.getVolumeR());
|
||||
}
|
||||
|
||||
const auto endFrameTime = std::chrono::high_resolution_clock::now();
|
||||
using namespace std::chrono_literals;
|
||||
const auto frameTimeMs = std::chrono::duration<double>(endFrameTime - startFrameTime) / 1ms;
|
||||
avgFps += frameTimeMs;
|
||||
|
||||
sampledFps++;
|
||||
|
||||
if (const auto elapsedSinceLastSample = std::chrono::duration<double>(endFrameTime - lastSample) / 1s;
|
||||
elapsedSinceLastSample >= 1.0) {
|
||||
if (!oneSecondPassed) {
|
||||
oneSecondPassed = true;
|
||||
return;
|
||||
while(!shouldExit) {
|
||||
if(!core.romLoaded) {
|
||||
std::this_thread::sleep_for(1ms);
|
||||
continue;
|
||||
}
|
||||
avgFps /= sampledFps;
|
||||
fps = 1000.0 / avgFps;
|
||||
|
||||
if(core.pause) {
|
||||
std::this_thread::sleep_for(1ms);
|
||||
continue;
|
||||
}
|
||||
|
||||
core.Run(settings.getVolumeL(), settings.getVolumeR());
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(presentMutex);
|
||||
memcpy(rdramCopy.data(), core.GetMem().GetRDRAMPtr(), RDRAM_SIZE);
|
||||
}
|
||||
readyForPresentation.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
void EmuThread::create() noexcept {
|
||||
shouldExit.store(false, std::memory_order_release);
|
||||
std::thread worker(&EmuThread::run, this);
|
||||
worker.detach();
|
||||
}
|
||||
|
||||
void EmuThread::TogglePause() const noexcept {
|
||||
n64::Core::GetInstance().TogglePause();
|
||||
}
|
||||
|
||||
void EmuThread::Reset() const noexcept {
|
||||
n64::Core::GetInstance().Reset();
|
||||
void EmuThread::Reset() noexcept {
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
core.Reset();
|
||||
rdramCopy = core.GetMem().GetRDRAM();
|
||||
}
|
||||
|
||||
void EmuThread::Stop() const noexcept {
|
||||
void EmuThread::Stop() noexcept {
|
||||
shouldExit.store(true, std::memory_order_release);
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
core.Stop();
|
||||
core.rom = {};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <RenderWidget.hpp>
|
||||
#include <SettingsWindow.hpp>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
|
||||
namespace n64 {
|
||||
struct Core;
|
||||
@@ -12,12 +13,17 @@ class EmuThread final {
|
||||
public:
|
||||
explicit EmuThread(double &, SettingsWindow &) noexcept;
|
||||
~EmuThread() = default;
|
||||
void run() const noexcept;
|
||||
void create() noexcept;
|
||||
void run() noexcept;
|
||||
void TogglePause() const noexcept;
|
||||
void Reset() const noexcept;
|
||||
void Stop() const noexcept;
|
||||
void Reset() noexcept;
|
||||
void Stop() noexcept;
|
||||
|
||||
bool interruptionRequested = false, parallelRDPInitialized = false;
|
||||
SettingsWindow &settings;
|
||||
double& fps;
|
||||
std::atomic_bool shouldExit = false;
|
||||
std::mutex presentMutex;
|
||||
std::condition_variable readyForPresentation;
|
||||
std::vector<u8> rdramCopy;
|
||||
};
|
||||
|
||||
@@ -4,8 +4,11 @@
|
||||
#include <ImGuiImpl/ProgressIndicators.hpp>
|
||||
#include <ImGuiImpl/StatusBar.hpp>
|
||||
#include <resources/gamecontrollerdb.h>
|
||||
#include <chrono>
|
||||
|
||||
KaizenGui::KaizenGui() noexcept : window("Kaizen " KAIZEN_VERSION_STR, 1280, 720), settingsWindow(window), vulkanWidget(window.getHandle()), emuThread(fpsCounter, settingsWindow) {
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
KaizenGui::KaizenGui() noexcept : window("Kaizen " KAIZEN_VERSION_STR, 1280, 720), settingsWindow(window), emuThread(fpsCounter, settingsWindow), vulkanWidget(window.getHandle(), emuThread.rdramCopy.data()) {
|
||||
gui::Initialize(n64::Core::GetInstance().parallel.wsi, window.getHandle());
|
||||
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
||||
|
||||
@@ -412,16 +415,21 @@ void KaizenGui::RenderUI() {
|
||||
return;
|
||||
|
||||
if(core.romLoaded) {
|
||||
core.parallel.UpdateScreen<true>();
|
||||
std::unique_lock<std::mutex> lk(emuThread.presentMutex);
|
||||
if(emuThread.readyForPresentation.wait_for(lk, 16.6667ms) == std::cv_status::no_timeout)
|
||||
core.parallel.UpdateScreen<true>();
|
||||
else
|
||||
core.parallel.UpdateScreen<false>();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
core.parallel.UpdateScreen<false>();
|
||||
}
|
||||
|
||||
void KaizenGui::LoadROM(const std::string &path) noexcept {
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
core.LoadROM(path);
|
||||
emuThread.create();
|
||||
const auto gameNameDB = n64::Core::GetMem().rom.gameNameDB;
|
||||
SDL_SetWindowTitle(window.getHandle(), ("Kaizen " KAIZEN_VERSION_STR " - " + gameNameDB).c_str());
|
||||
}
|
||||
@@ -449,8 +457,6 @@ void KaizenGui::run() {
|
||||
}
|
||||
|
||||
SDL_GetWindowSize(window.getHandle(), &width, &height);
|
||||
|
||||
emuThread.run();
|
||||
RenderUI();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ public:
|
||||
bool minimized = false;
|
||||
|
||||
SettingsWindow settingsWindow;
|
||||
RenderWidget vulkanWidget;
|
||||
EmuThread emuThread;
|
||||
RenderWidget vulkanWidget;
|
||||
Debugger debugger;
|
||||
|
||||
SDL_Gamepad* gamepad = nullptr;
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
#include <SDL3/SDL.h>
|
||||
#include <imgui_impl_sdl3.h>
|
||||
|
||||
RenderWidget::RenderWidget(SDL_Window* window) {
|
||||
RenderWidget::RenderWidget(SDL_Window* window, u8* rdram) {
|
||||
wsiPlatform = std::make_shared<SDLWSIPlatform>(window);
|
||||
windowInfo = std::make_shared<SDLParallelRdpWindowInfo>(window);
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
core.parallel.Init(wsiPlatform, windowInfo, core.GetMem().GetRDRAMPtr());
|
||||
core.parallel.Init(wsiPlatform, windowInfo, rdram);
|
||||
}
|
||||
@@ -72,7 +72,7 @@ private:
|
||||
|
||||
class RenderWidget final {
|
||||
public:
|
||||
explicit RenderWidget(SDL_Window*);
|
||||
explicit RenderWidget(SDL_Window*, u8* rdram);
|
||||
|
||||
std::shared_ptr<ParallelRDP::WindowInfo> windowInfo;
|
||||
std::shared_ptr<SDLWSIPlatform> wsiPlatform;
|
||||
|
||||
Reference in New Issue
Block a user