attempt moving core to separate thread again

This commit is contained in:
2026-04-13 18:00:45 +02:00
parent fda755f7d8
commit ad6007b254
6 changed files with 58 additions and 43 deletions
+34 -31
View File
@@ -1,52 +1,55 @@
#include <Core.hpp> #include <Core.hpp>
#include <EmuThread.hpp> #include <EmuThread.hpp>
#include <KaizenGui.hpp> #include <KaizenGui.hpp>
#include <chrono>
#include <thread>
using namespace std::chrono_literals;
EmuThread::EmuThread(double &fps, SettingsWindow &settings) noexcept : settings(settings), fps(fps) {} 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(); n64::Core& core = n64::Core::GetInstance();
if(!core.romLoaded) return; rdramCopy = core.GetMem().GetRDRAM();
auto lastSample = std::chrono::high_resolution_clock::now();
auto avgFps = 16.667;
auto sampledFps = 0;
static bool oneSecondPassed = false;
fps = 1000.0 / avgFps; while(!shouldExit) {
if(!core.romLoaded) {
const auto startFrameTime = std::chrono::high_resolution_clock::now(); std::this_thread::sleep_for(1ms);
if (!core.pause) { continue;
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;
} }
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 { void EmuThread::TogglePause() const noexcept {
n64::Core::GetInstance().TogglePause(); n64::Core::GetInstance().TogglePause();
} }
void EmuThread::Reset() const noexcept { void EmuThread::Reset() noexcept {
n64::Core::GetInstance().Reset(); 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(); n64::Core& core = n64::Core::GetInstance();
core.Stop(); core.Stop();
core.rom = {}; core.rom = {};
+9 -3
View File
@@ -2,6 +2,7 @@
#include <RenderWidget.hpp> #include <RenderWidget.hpp>
#include <SettingsWindow.hpp> #include <SettingsWindow.hpp>
#include <memory> #include <memory>
#include <atomic>
namespace n64 { namespace n64 {
struct Core; struct Core;
@@ -12,12 +13,17 @@ class EmuThread final {
public: public:
explicit EmuThread(double &, SettingsWindow &) noexcept; explicit EmuThread(double &, SettingsWindow &) noexcept;
~EmuThread() = default; ~EmuThread() = default;
void run() const noexcept; void create() noexcept;
void run() noexcept;
void TogglePause() const noexcept; void TogglePause() const noexcept;
void Reset() const noexcept; void Reset() noexcept;
void Stop() const noexcept; void Stop() noexcept;
bool interruptionRequested = false, parallelRDPInitialized = false; bool interruptionRequested = false, parallelRDPInitialized = false;
SettingsWindow &settings; SettingsWindow &settings;
double& fps; double& fps;
std::atomic_bool shouldExit = false;
std::mutex presentMutex;
std::condition_variable readyForPresentation;
std::vector<u8> rdramCopy;
}; };
+11 -5
View File
@@ -4,8 +4,11 @@
#include <ImGuiImpl/ProgressIndicators.hpp> #include <ImGuiImpl/ProgressIndicators.hpp>
#include <ImGuiImpl/StatusBar.hpp> #include <ImGuiImpl/StatusBar.hpp>
#include <resources/gamecontrollerdb.h> #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()); gui::Initialize(n64::Core::GetInstance().parallel.wsi, window.getHandle());
SDL_InitSubSystem(SDL_INIT_GAMEPAD); SDL_InitSubSystem(SDL_INIT_GAMEPAD);
@@ -412,16 +415,21 @@ void KaizenGui::RenderUI() {
return; return;
if(core.romLoaded) { 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; return;
} }
core.parallel.UpdateScreen<false>(); core.parallel.UpdateScreen<false>();
} }
void KaizenGui::LoadROM(const std::string &path) noexcept { void KaizenGui::LoadROM(const std::string &path) noexcept {
n64::Core& core = n64::Core::GetInstance(); n64::Core& core = n64::Core::GetInstance();
core.LoadROM(path); core.LoadROM(path);
emuThread.create();
const auto gameNameDB = n64::Core::GetMem().rom.gameNameDB; const auto gameNameDB = n64::Core::GetMem().rom.gameNameDB;
SDL_SetWindowTitle(window.getHandle(), ("Kaizen " KAIZEN_VERSION_STR " - " + gameNameDB).c_str()); SDL_SetWindowTitle(window.getHandle(), ("Kaizen " KAIZEN_VERSION_STR " - " + gameNameDB).c_str());
} }
@@ -449,8 +457,6 @@ void KaizenGui::run() {
} }
SDL_GetWindowSize(window.getHandle(), &width, &height); SDL_GetWindowSize(window.getHandle(), &width, &height);
emuThread.run();
RenderUI(); RenderUI();
} }
} }
+1 -1
View File
@@ -17,8 +17,8 @@ public:
bool minimized = false; bool minimized = false;
SettingsWindow settingsWindow; SettingsWindow settingsWindow;
RenderWidget vulkanWidget;
EmuThread emuThread; EmuThread emuThread;
RenderWidget vulkanWidget;
Debugger debugger; Debugger debugger;
SDL_Gamepad* gamepad = nullptr; SDL_Gamepad* gamepad = nullptr;
+2 -2
View File
@@ -4,9 +4,9 @@
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <imgui_impl_sdl3.h> #include <imgui_impl_sdl3.h>
RenderWidget::RenderWidget(SDL_Window* window) { RenderWidget::RenderWidget(SDL_Window* window, u8* rdram) {
wsiPlatform = std::make_shared<SDLWSIPlatform>(window); wsiPlatform = std::make_shared<SDLWSIPlatform>(window);
windowInfo = std::make_shared<SDLParallelRdpWindowInfo>(window); windowInfo = std::make_shared<SDLParallelRdpWindowInfo>(window);
n64::Core& core = n64::Core::GetInstance(); n64::Core& core = n64::Core::GetInstance();
core.parallel.Init(wsiPlatform, windowInfo, core.GetMem().GetRDRAMPtr()); core.parallel.Init(wsiPlatform, windowInfo, rdram);
} }
+1 -1
View File
@@ -72,7 +72,7 @@ private:
class RenderWidget final { class RenderWidget final {
public: public:
explicit RenderWidget(SDL_Window*); explicit RenderWidget(SDL_Window*, u8* rdram);
std::shared_ptr<ParallelRDP::WindowInfo> windowInfo; std::shared_ptr<ParallelRDP::WindowInfo> windowInfo;
std::shared_ptr<SDLWSIPlatform> wsiPlatform; std::shared_ptr<SDLWSIPlatform> wsiPlatform;