mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-17 15:37:39 +00:00
Merge pull request #7202 from unknownbrackets/cpu-thread
Allow switching cpu thread on/off ingame
This commit is contained in:
commit
f74add91e2
@ -63,8 +63,10 @@ enum CPUThreadState {
|
||||
CPU_THREAD_STARTING,
|
||||
CPU_THREAD_RUNNING,
|
||||
CPU_THREAD_SHUTDOWN,
|
||||
CPU_THREAD_QUIT,
|
||||
|
||||
CPU_THREAD_EXECUTE,
|
||||
CPU_THREAD_RESUME,
|
||||
};
|
||||
|
||||
MetaFileSystem pspFileSystem;
|
||||
@ -73,7 +75,7 @@ static GlobalUIState globalUIState;
|
||||
static CoreParameter coreParameter;
|
||||
static FileLoader *loadedFile;
|
||||
static PSPMixer *mixer;
|
||||
static std::thread *cpuThread = NULL;
|
||||
static std::thread *cpuThread = nullptr;
|
||||
static std::thread::id cpuThreadID;
|
||||
static recursive_mutex cpuThreadLock;
|
||||
static condition_variable cpuThreadCond;
|
||||
@ -110,7 +112,7 @@ void Audio_Init() {
|
||||
}
|
||||
|
||||
bool IsOnSeparateCPUThread() {
|
||||
if (cpuThread != NULL) {
|
||||
if (cpuThread != nullptr) {
|
||||
return cpuThreadID == std::this_thread::get_id();
|
||||
} else {
|
||||
return false;
|
||||
@ -269,14 +271,14 @@ void CPU_RunLoop() {
|
||||
setCurrentThreadName("CPU");
|
||||
FPU_SetFastMode();
|
||||
|
||||
if (!CPU_NextState(CPU_THREAD_PENDING, CPU_THREAD_STARTING)) {
|
||||
if (CPU_NextState(CPU_THREAD_PENDING, CPU_THREAD_STARTING)) {
|
||||
CPU_Init();
|
||||
CPU_NextState(CPU_THREAD_STARTING, CPU_THREAD_RUNNING);
|
||||
} else if (!CPU_NextState(CPU_THREAD_RESUME, CPU_THREAD_RUNNING)) {
|
||||
ERROR_LOG(CPU, "CPU thread in unexpected state: %d", cpuThreadState);
|
||||
return;
|
||||
}
|
||||
|
||||
CPU_Init();
|
||||
CPU_NextState(CPU_THREAD_STARTING, CPU_THREAD_RUNNING);
|
||||
|
||||
while (cpuThreadState != CPU_THREAD_SHUTDOWN)
|
||||
{
|
||||
CPU_WaitStatus(cpuThreadCond, &CPU_HasPendingAction);
|
||||
@ -292,6 +294,11 @@ void CPU_RunLoop() {
|
||||
case CPU_THREAD_SHUTDOWN:
|
||||
break;
|
||||
|
||||
case CPU_THREAD_QUIT:
|
||||
// Just leave the thread, CPU is switching off thread.
|
||||
CPU_SetState(CPU_THREAD_NOT_RUNNING);
|
||||
return;
|
||||
|
||||
default:
|
||||
ERROR_LOG(CPU, "CPU thread in unexpected state: %d", cpuThreadState);
|
||||
// Begin shutdown, otherwise we'd just spin on this bad state.
|
||||
@ -426,7 +433,7 @@ void PSP_Shutdown() {
|
||||
if (coreState == CORE_RUNNING)
|
||||
Core_UpdateState(CORE_ERROR);
|
||||
Core_NotifyShutdown();
|
||||
if (cpuThread != NULL) {
|
||||
if (cpuThread != nullptr) {
|
||||
CPU_NextStateNot(CPU_THREAD_NOT_RUNNING, CPU_THREAD_SHUTDOWN);
|
||||
CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsShutdown);
|
||||
delete cpuThread;
|
||||
@ -451,7 +458,31 @@ void PSP_RunLoopUntil(u64 globalticks) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpuThread != NULL) {
|
||||
// Switch the CPU thread on or off, as the case may be.
|
||||
bool useCPUThread = g_Config.bSeparateCPUThread;
|
||||
if (useCPUThread && cpuThread == nullptr) {
|
||||
// Need to start the cpu thread.
|
||||
Core_ListenShutdown(System_Wake);
|
||||
CPU_SetState(CPU_THREAD_RESUME);
|
||||
cpuThread = new std::thread(&CPU_RunLoop);
|
||||
cpuThreadID = cpuThread->get_id();
|
||||
cpuThread->detach();
|
||||
if (gpu) {
|
||||
gpu->SetThreadEnabled(true);
|
||||
}
|
||||
CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady);
|
||||
} else if (!useCPUThread && cpuThread != nullptr) {
|
||||
CPU_SetState(CPU_THREAD_QUIT);
|
||||
CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsShutdown);
|
||||
delete cpuThread;
|
||||
cpuThread = nullptr;
|
||||
cpuThreadID = std::thread::id();
|
||||
if (gpu) {
|
||||
gpu->SetThreadEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (cpuThread != nullptr) {
|
||||
// Tell the gpu a new frame is about to begin, before we start the CPU.
|
||||
gpu->SyncBeginFrame();
|
||||
|
||||
|
@ -543,7 +543,7 @@ void DIRECTX9_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferForma
|
||||
|
||||
bool DIRECTX9_GPU::FramebufferDirty() {
|
||||
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
|
||||
if (g_Config.bSeparateCPUThread) {
|
||||
if (ThreadEnabled()) {
|
||||
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
|
||||
ScheduleEvent(GPU_EVENT_PROCESS_QUEUE);
|
||||
// Allow it to process fully before deciding if it's dirty.
|
||||
@ -559,7 +559,7 @@ bool DIRECTX9_GPU::FramebufferDirty() {
|
||||
}
|
||||
bool DIRECTX9_GPU::FramebufferReallyDirty() {
|
||||
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
|
||||
if (g_Config.bSeparateCPUThread) {
|
||||
if (ThreadEnabled()) {
|
||||
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
|
||||
ScheduleEvent(GPU_EVENT_PROCESS_QUEUE);
|
||||
// Allow it to process fully before deciding if it's dirty.
|
||||
|
@ -615,7 +615,7 @@ void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat fo
|
||||
}
|
||||
|
||||
bool GLES_GPU::FramebufferDirty() {
|
||||
if (g_Config.bSeparateCPUThread) {
|
||||
if (ThreadEnabled()) {
|
||||
// Allow it to process fully before deciding if it's dirty.
|
||||
SyncThread();
|
||||
}
|
||||
@ -630,7 +630,7 @@ bool GLES_GPU::FramebufferDirty() {
|
||||
}
|
||||
|
||||
bool GLES_GPU::FramebufferReallyDirty() {
|
||||
if (g_Config.bSeparateCPUThread) {
|
||||
if (ThreadEnabled()) {
|
||||
// Allow it to process fully before deciding if it's dirty.
|
||||
SyncThread();
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ bool GPUCommon::BusyDrawing() {
|
||||
}
|
||||
|
||||
u32 GPUCommon::DrawSync(int mode) {
|
||||
if (g_Config.bSeparateCPUThread) {
|
||||
if (ThreadEnabled()) {
|
||||
// Sync first, because the CPU is usually faster than the emulated GPU.
|
||||
SyncThread();
|
||||
}
|
||||
@ -124,7 +124,7 @@ void GPUCommon::CheckDrawSync() {
|
||||
}
|
||||
|
||||
int GPUCommon::ListSync(int listid, int mode) {
|
||||
if (g_Config.bSeparateCPUThread) {
|
||||
if (ThreadEnabled()) {
|
||||
// Sync first, because the CPU is usually faster than the emulated GPU.
|
||||
SyncThread();
|
||||
}
|
||||
|
@ -275,6 +275,7 @@ public:
|
||||
virtual bool FramebufferDirty() = 0;
|
||||
virtual bool FramebufferReallyDirty() = 0;
|
||||
virtual bool BusyDrawing() = 0;
|
||||
virtual void SetThreadEnabled(bool threadEnabled) = 0;
|
||||
|
||||
// If any jit is being used inside the GPU.
|
||||
virtual bool DescribeCodePtr(const u8 *ptr, std::string &name) = 0;
|
||||
|
@ -390,7 +390,7 @@ void GameSettingsScreen::CreateViews() {
|
||||
systemSettings->Add(new ItemHeader(s->T("Emulation")));
|
||||
systemSettings->Add(new CheckBox(&g_Config.bFastMemory, s->T("Fast Memory", "Fast Memory (Unstable)")))->OnClick.Handle(this, &GameSettingsScreen::OnJitAffectingSetting);
|
||||
|
||||
systemSettings->Add(new CheckBox(&g_Config.bSeparateCPUThread, s->T("Multithreaded (experimental)")))->SetEnabled(!PSP_IsInited());
|
||||
systemSettings->Add(new CheckBox(&g_Config.bSeparateCPUThread, s->T("Multithreaded (experimental)")));
|
||||
systemSettings->Add(new CheckBox(&g_Config.bSeparateIOThread, s->T("I/O on thread (experimental)")))->SetEnabled(!PSP_IsInited());
|
||||
systemSettings->Add(new CheckBox(&g_Config.bForceLagSync, s->T("Force real clock sync (slower, less lag)")));
|
||||
systemSettings->Add(new PopupSliderChoice(&g_Config.iLockedCPUSpeed, 0, 1000, s->T("Change CPU Clock", "Change CPU Clock (0 = default) (unstable)"), screenManager()));
|
||||
|
Loading…
x
Reference in New Issue
Block a user