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 <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 = {};
+9 -3
View File
@@ -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;
};
+11 -5
View File
@@ -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();
}
}
+1 -1
View File
@@ -17,8 +17,8 @@ public:
bool minimized = false;
SettingsWindow settingsWindow;
RenderWidget vulkanWidget;
EmuThread emuThread;
RenderWidget vulkanWidget;
Debugger debugger;
SDL_Gamepad* gamepad = nullptr;
+2 -2
View File
@@ -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);
}
+1 -1
View File
@@ -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;