mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Minor EmuThread refactor
This commit is contained in:
1 parent
edd968062a
commit
5eb4772644
9 files changed
+41
-32
No files matched your search
@@ -14,5 +14,4 @@ public:
|
||||
virtual ~Application() = default;
|
||||
virtual bool InitGraphics(GraphicsContext *graphicsContext) = 0;
|
||||
virtual void ShutdownGraphics(GraphicsContext *graphicsContext) = 0;
|
||||
virtual void Frame(GraphicsContext *graphicsContext) = 0;
|
||||
};
|
||||
@@ -117,7 +117,4 @@ public:
|
||||
void ShutdownGraphics(GraphicsContext *graphicsContext) override {
|
||||
NativeShutdownGraphics(graphicsContext);
|
||||
}
|
||||
void Frame(GraphicsContext *graphicsContext) override {
|
||||
NativeFrame(graphicsContext);
|
||||
}
|
||||
};
|
||||
+11
-18
@@ -36,7 +36,7 @@ bool MainThread_Ready() {
|
||||
return g_inLoop;
|
||||
}
|
||||
|
||||
static void EmuThreadFunc(GraphicsContext *graphicsContext, Application *application, std::function<void()> postFrame) {
|
||||
static void EmuThreadFunc(GraphicsContext *graphicsContext, Application *application, std::function<bool (GraphicsContext *)> frame) {
|
||||
INFO_LOG(Log::G3D, "Entering separate emu thread");
|
||||
SetCurrentThreadName("EmuThread");
|
||||
|
||||
@@ -57,11 +57,7 @@ static void EmuThreadFunc(GraphicsContext *graphicsContext, Application *applica
|
||||
// We're here again, so the game quit. Restart Run() which controls the UI.
|
||||
// This way they can load a new game.
|
||||
// This normally calls NativeFrame()
|
||||
application->Frame(graphicsContext);
|
||||
if (postFrame) {
|
||||
postFrame();
|
||||
}
|
||||
if (GetUIState() == UISTATE_EXIT) {
|
||||
if (!frame(graphicsContext)) {
|
||||
g_emuThreadState = EmuThreadState::QUIT_REQUESTED;
|
||||
}
|
||||
}
|
||||
@@ -77,10 +73,10 @@ static void EmuThreadFunc(GraphicsContext *graphicsContext, Application *applica
|
||||
g_emuThreadState = EmuThreadState::STOPPED;
|
||||
}
|
||||
|
||||
std::thread EmuThread_Start(GraphicsContext *graphicsContext, Application *application, std::function<void()> postFrame) {
|
||||
std::thread EmuThread_Start(GraphicsContext *graphicsContext, Application *application, std::function<bool(GraphicsContext *)> frame) {
|
||||
INFO_LOG(Log::System, "EmuTread_Start");
|
||||
_dbg_assert_(g_emuThreadState == EmuThreadState::STOPPED);
|
||||
std::thread emuThread = std::thread(&EmuThreadFunc, graphicsContext, application, postFrame);
|
||||
std::thread emuThread = std::thread(&EmuThreadFunc, graphicsContext, application, frame);
|
||||
graphicsContext->ThreadStart();
|
||||
return emuThread;
|
||||
}
|
||||
@@ -98,7 +94,7 @@ void EmuThread_Join(GraphicsContext *graphicsContext, std::thread &emuThread) {
|
||||
graphicsContext->ThreadEnd();
|
||||
}
|
||||
|
||||
bool RunMainLoop(GraphicsContext *graphicsContext, Application *application, std::function<bool()> runCondition, std::function<void()> postFrame) {
|
||||
bool RunMainLoop(GraphicsContext *graphicsContext, Application *application, std::function<bool(GraphicsContext *)> frame) {
|
||||
// This is the main thread. the graphics contexts will spawn and handle its own threads if needed.
|
||||
// InitFromRenderThread/ShutdownFromRenderThread are not used.
|
||||
|
||||
@@ -109,19 +105,17 @@ bool RunMainLoop(GraphicsContext *graphicsContext, Application *application, std
|
||||
|
||||
g_inLoop = true;
|
||||
|
||||
while (runCondition()) {
|
||||
while (frame(graphicsContext)) {
|
||||
// We're here again, so the game quit. Restart Run() which controls the UI.
|
||||
// This way they can load a new game.
|
||||
application->Frame(graphicsContext);
|
||||
postFrame();
|
||||
}
|
||||
|
||||
// NOTE: Don't call stuff like Core_Stop here. On Android, we fully shut down graphics when you switch away from the app,
|
||||
// then boot it up again when returning. That means stopping this thread and restarting it.
|
||||
|
||||
// Process the shutdown. Without this, non-GL delays 800ms on shutdown.
|
||||
// Process the shutdown. Without this, non-GL delays 800ms on shutdown. TODO: is this still an issue?
|
||||
Core_StateProcessed();
|
||||
application->Frame(graphicsContext);
|
||||
frame(graphicsContext);
|
||||
|
||||
g_inLoop = false;
|
||||
|
||||
@@ -131,7 +125,7 @@ bool RunMainLoop(GraphicsContext *graphicsContext, Application *application, std
|
||||
}
|
||||
|
||||
// Call InitAPI and ShutdownAPI outside this!
|
||||
bool MainThreadFunc(GraphicsContext *graphicsContext, Application *application, WindowSystem windowSystem, void *windowData1, void *windowData2, std::function<void()> postFrame) {
|
||||
bool MainThreadFunc(GraphicsContext *graphicsContext, Application *application, WindowSystem windowSystem, void *windowData1, void *windowData2, std::function<bool(GraphicsContext *)> frame) {
|
||||
// This is now the render thread, and will spawn the emu thread below.
|
||||
std::string error_string;
|
||||
bool success = graphicsContext->InitSurface(windowSystem, windowData1, windowData2, &error_string);
|
||||
@@ -146,7 +140,7 @@ bool MainThreadFunc(GraphicsContext *graphicsContext, Application *application,
|
||||
DEBUG_LOG(Log::Boot, "Done.");
|
||||
|
||||
g_inLoop = true;
|
||||
std::thread emuThread = EmuThread_Start(graphicsContext, application, postFrame);
|
||||
std::thread emuThread = EmuThread_Start(graphicsContext, application, frame);
|
||||
graphicsContext->ThreadStart();
|
||||
// This thread becomes the render thread. EmuThread will tell it when to quit by sending a message.
|
||||
while (graphicsContext->ThreadFrame()) {}
|
||||
@@ -160,9 +154,8 @@ bool MainThreadFunc(GraphicsContext *graphicsContext, Application *application,
|
||||
} else {
|
||||
SetCurrentThreadName("MainThread");
|
||||
|
||||
RunMainLoop(graphicsContext, application, []() { return GetUIState() != UISTATE_EXIT; }, postFrame);
|
||||
RunMainLoop(graphicsContext, application, frame);
|
||||
}
|
||||
|
||||
graphicsContext->ShutdownSurface();
|
||||
return true;
|
||||
}
|
||||
+3
-3
@@ -31,16 +31,16 @@ class GraphicsContext;
|
||||
// This should be used by platforms that launch a separate thread and doesn't
|
||||
// need to run a polling loop in it.
|
||||
// NOTE: Does take ownership over Application (which is just a wrapper for NativeInitGraphics/NativeShutdownGraphics/NativeFrame).
|
||||
bool MainThreadFunc(GraphicsContext * graphicsContext, Application *application, WindowSystem windowSystem, void *windowData1, void *windowData2, std::function<void()> postFrame);
|
||||
bool MainThreadFunc(GraphicsContext * graphicsContext, Application *application, WindowSystem windowSystem, void *windowData1, void *windowData2, std::function<bool(GraphicsContext *)> frame);
|
||||
|
||||
// If you're not using MainThreadFunc, you can at least use these to manage a spinning EmuThread (that calls NativeFrame),
|
||||
// whether your graphics context requires multithreading or not. Then use RunMainLoop to implement your main loop for
|
||||
// the case where a separate EmuThread is not needed.
|
||||
// NOTE: Does take ownership over Application (which is just a wrapper for NativeInitGraphics/NativeShutdownGraphics/NativeFrame).
|
||||
std::thread EmuThread_Start(GraphicsContext *graphicsContext, Application *application, std::function<void()> postFrame);
|
||||
std::thread EmuThread_Start(GraphicsContext *graphicsContext, Application *application, std::function<bool(GraphicsContext *)> frame);
|
||||
void EmuThread_RequestExit(); // Useful when the render thread is in control like on Android.
|
||||
void EmuThread_Join(GraphicsContext *graphicsContext, std::thread &emuThread);
|
||||
|
||||
// Call from the main thread.
|
||||
// NOTE: Does take ownership over Application (which is just a wrapper for NativeInitGraphics/NativeShutdownGraphics/NativeFrame).
|
||||
bool RunMainLoop(GraphicsContext *graphicsContext, Application *application, std::function<bool()> runCondition, std::function<void()> postFrame);
|
||||
bool RunMainLoop(GraphicsContext *graphicsContext, Application *application, std::function<bool(GraphicsContext *)> frame);
|
||||
+3
-1
@@ -879,8 +879,10 @@ void MainUI::initializeGL() {
|
||||
graphicsContext->InitAPI(nullptr, nullptr, &errorMessage);
|
||||
graphicsContext->InitSurface(WINDOWSYSTEM_NONE, nullptr, nullptr, &errorMessage);
|
||||
INFO_LOG(Log::System, "Using thread, starting emu thread");
|
||||
emuThread_ = EmuThread_Start(graphicsContext, new NativeApplication(), [this](){
|
||||
emuThread_ = EmuThread_Start(graphicsContext, new NativeApplication(), [this](GraphicsContext *graphicsContext){
|
||||
NativeFrame(graphicsContext);
|
||||
updateAccelerometer();
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
INFO_LOG(Log::System, "Not using thread, backend=%d", (int)g_Config.iGPUBackend);
|
||||
|
||||
+8
-2
@@ -2211,7 +2211,10 @@ int main(int argc, char *argv[]) {
|
||||
const bool mainThreadIsRender = graphicsContext->NeedsSeparateEmuThread();
|
||||
if (!mainThreadIsRender) {
|
||||
// TODO: This shouldn't be the EmuThread, but rather RunMainLoop?
|
||||
std::thread emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), nullptr);
|
||||
std::thread emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), [](GraphicsContext *graphicsContext){
|
||||
NativeFrame(graphicsContext);
|
||||
return true;
|
||||
});
|
||||
// Vulkan mode uses this.
|
||||
// We should only be a message pump. This allows for lower latency
|
||||
// input events, and so on. The spawned EmuThread runs emulation and rendering.
|
||||
@@ -2243,7 +2246,10 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
EmuThread_Join(graphicsContext, emuThread);
|
||||
} else {
|
||||
std::thread emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), nullptr);
|
||||
std::thread emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), [](GraphicsContext *graphicsContext){
|
||||
NativeFrame(graphicsContext);
|
||||
return true;
|
||||
});
|
||||
while (true) {
|
||||
// OpenGL mode uses this.
|
||||
{
|
||||
|
||||
+6
-1
@@ -1233,6 +1233,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
|
||||
System_Notify(SystemNotification::UI);
|
||||
|
||||
std::thread mainThread = std::thread([]() {
|
||||
// TODO: We can really merge all of this into MainThreadFunc
|
||||
std::string errorMessage;
|
||||
std::string *deviceNameSetting;
|
||||
std::unique_ptr<GraphicsContext> graphicsContext(CreateGraphicsContext((GPUBackend)g_Config.iGPUBackend, &deviceNameSetting));
|
||||
@@ -1240,7 +1241,11 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
|
||||
HandleGraphicsFailure(errorMessage);
|
||||
return;
|
||||
}
|
||||
if (!MainThreadFunc(graphicsContext.get(), new NativeApplication(), WINDOWSYSTEM_WIN32, MainWindow::GetHInstance(), MainWindow::GetHWND(), []() {})) {
|
||||
if (!MainThreadFunc(graphicsContext.get(), new NativeApplication(), WINDOWSYSTEM_WIN32, MainWindow::GetHInstance(), MainWindow::GetHWND(),
|
||||
[](GraphicsContext *graphicsContext) {
|
||||
NativeFrame(graphicsContext);
|
||||
return GetUIState() != UISTATE_EXIT;
|
||||
})) {
|
||||
HandleGraphicsFailure("Failed to initialize main thread function.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -958,8 +958,10 @@ extern "C" jboolean Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * e
|
||||
}, nullptr);
|
||||
|
||||
// This is where we start the emuthread now - after InitFromRenderThread. This eliminates a race condition.
|
||||
g_emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), []() {
|
||||
g_emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), [](GraphicsContext *graphicsContext) {
|
||||
NativeFrame(graphicsContext);
|
||||
ProcessFrameCommands();
|
||||
return true;
|
||||
});
|
||||
renderer_inited = true;
|
||||
} else {
|
||||
@@ -985,8 +987,10 @@ extern "C" jboolean Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * e
|
||||
g_OSD.Show(OSDType::MESSAGE_ERROR, details, 5.0);
|
||||
}, nullptr);
|
||||
|
||||
g_emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), []() {
|
||||
g_emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), [](GraphicsContext *graphicsContext) {
|
||||
NativeFrame(graphicsContext);
|
||||
ProcessFrameCommands();
|
||||
return true;
|
||||
});
|
||||
|
||||
INFO_LOG(Log::G3D, "Restored.");
|
||||
|
||||
@@ -83,7 +83,10 @@ PPSSPPBaseViewController *sharedViewController;
|
||||
return false;
|
||||
}
|
||||
|
||||
g_emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), [](){});
|
||||
g_emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), [](GraphicsContext *graphicsContext){
|
||||
NativeFrame(graphicsContext);
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user