mirror of
https://github.com/OpenEmu/PPSSPP-Core.git
synced 2025-11-01 11:05:49 +00:00
Fix threads for optimized loadStates
This commit is contained in:
+30
-24
@@ -65,7 +65,6 @@
|
||||
KeyInput input_state;
|
||||
OnScreenMessages osm;
|
||||
|
||||
|
||||
namespace OpenEmuCoreThread {
|
||||
OpenEmuGLContext *ctx;
|
||||
|
||||
@@ -80,10 +79,12 @@ namespace OpenEmuCoreThread {
|
||||
};
|
||||
|
||||
static std::thread emuThread;
|
||||
std::atomic<EmuThreadState> emuThreadState(EmuThreadState::DISABLED);
|
||||
static bool threadStarted = false;
|
||||
static std::atomic<EmuThreadState> emuThreadState(EmuThreadState::DISABLED);
|
||||
|
||||
static void EmuFrame() {
|
||||
ctx->SetRenderTarget();
|
||||
|
||||
if (ctx->GetDrawContext()) {
|
||||
ctx->GetDrawContext()->BeginFrame();
|
||||
}
|
||||
@@ -106,6 +107,7 @@ namespace OpenEmuCoreThread {
|
||||
while (true) {
|
||||
switch ((EmuThreadState)emuThreadState) {
|
||||
case EmuThreadState::START_REQUESTED:
|
||||
threadStarted = true;
|
||||
emuThreadState = EmuThreadState::RUNNING;
|
||||
/* fallthrough */
|
||||
case EmuThreadState::RUNNING:
|
||||
@@ -115,7 +117,7 @@ namespace OpenEmuCoreThread {
|
||||
emuThreadState = EmuThreadState::PAUSED;
|
||||
/* fallthrough */
|
||||
case EmuThreadState::PAUSED:
|
||||
sleep(1);
|
||||
usleep(1000);
|
||||
break;
|
||||
default:
|
||||
case EmuThreadState::QUIT_REQUESTED:
|
||||
@@ -157,14 +159,17 @@ namespace OpenEmuCoreThread {
|
||||
return;
|
||||
}
|
||||
emuThreadState = EmuThreadState::PAUSE_REQUESTED;
|
||||
ctx->ThreadFrame();
|
||||
|
||||
while (emuThreadState != EmuThreadState::PAUSED) {
|
||||
sleep(1);
|
||||
//We need to process frames until the thread Pauses give 10 ms between loops
|
||||
ctx->ThreadFrame();
|
||||
emuThreadState = EmuThreadState::PAUSE_REQUESTED;
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OpenEmuCoreThread
|
||||
|
||||
|
||||
// Here's where we store the OpenEmu framebuffer to bind for final rendering
|
||||
int framebuffer = 0;
|
||||
|
||||
@@ -236,14 +241,12 @@ int NativeMix(short *audio, int num_samples)
|
||||
void NativeInit(int argc, const char *argv[], const char *savegame_directory, const char *external_directory, const char *installID, bool fs)
|
||||
{
|
||||
VFSRegister("", new DirectoryAssetReader("assets/"));
|
||||
//VFSRegister("", new DirectoryAssetReader(savegame_directory));
|
||||
VFSRegister("", new DirectoryAssetReader(external_directory));
|
||||
|
||||
if (host == nullptr) {
|
||||
host = new NativeHost();
|
||||
}
|
||||
|
||||
//g_Config.internalDataDirectory = savegame_directory;
|
||||
g_Config.externalDirectory = external_directory;
|
||||
|
||||
logger = new AndroidLogger();
|
||||
@@ -259,14 +262,25 @@ void NativeInit(int argc, const char *argv[], const char *savegame_directory, co
|
||||
}
|
||||
}
|
||||
|
||||
void NativeSetThreadState(OpenEmuCoreThread::EmuThreadState threadState) {
|
||||
if(threadState == OpenEmuCoreThread::EmuThreadState::PAUSE_REQUESTED && OpenEmuCoreThread::threadStarted)
|
||||
OpenEmuCoreThread::EmuThreadPause();
|
||||
else if(threadState == OpenEmuCoreThread::EmuThreadState::START_REQUESTED && !OpenEmuCoreThread::threadStarted)
|
||||
OpenEmuCoreThread::EmuThreadStart();
|
||||
else
|
||||
OpenEmuCoreThread::emuThreadState = threadState;
|
||||
}
|
||||
|
||||
bool NativeInitGraphics(GraphicsContext *graphicsContext)
|
||||
{
|
||||
//Set the Core Thread graphics Context
|
||||
OpenEmuCoreThread::ctx = static_cast<OpenEmuGLContext*>(graphicsContext);
|
||||
|
||||
// Save framebuffer and set ppsspp default graphics framebuffer object
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &framebuffer);
|
||||
|
||||
static_cast<OpenEmuGLContext*>(graphicsContext)->SetRenderFBO(framebuffer);
|
||||
|
||||
Core_SetGraphicsContext(graphicsContext);
|
||||
OpenEmuCoreThread::ctx->SetRenderFBO(framebuffer);
|
||||
|
||||
Core_SetGraphicsContext(OpenEmuCoreThread::ctx);
|
||||
|
||||
if (gpu)
|
||||
gpu->DeviceRestore();
|
||||
@@ -278,19 +292,11 @@ void NativeResized(){}
|
||||
|
||||
void NativeRender(GraphicsContext *ctx)
|
||||
{
|
||||
static_cast<OpenEmuGLContext*>(ctx)->SetRenderTarget();
|
||||
if(OpenEmuCoreThread::emuThreadState == OpenEmuCoreThread::EmuThreadState::PAUSED)
|
||||
return;
|
||||
|
||||
OpenEmuCoreThread::ctx = static_cast<OpenEmuGLContext*>(ctx);
|
||||
|
||||
if (OpenEmuCoreThread::emuThreadState != OpenEmuCoreThread::EmuThreadState::RUNNING) {
|
||||
OpenEmuCoreThread::EmuThreadStart();
|
||||
}
|
||||
|
||||
if (!ctx->ThreadFrame()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->SwapBuffers();
|
||||
OpenEmuCoreThread::ctx->ThreadFrame();
|
||||
OpenEmuCoreThread::ctx->SwapBuffers();
|
||||
}
|
||||
|
||||
void NativeUpdate() {}
|
||||
|
||||
@@ -7719,7 +7719,7 @@
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_ENABLE_CPP_RTTI = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_OPTIMIZATION_LEVEL = 3;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
USE_FFMPEG,
|
||||
_M_X64,
|
||||
@@ -7799,7 +7799,7 @@
|
||||
ENABLE_TESTABILITY = NO;
|
||||
GCC_ENABLE_CPP_RTTI = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_OPTIMIZATION_LEVEL = 3;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
USE_FFMPEG,
|
||||
_M_X64,
|
||||
|
||||
+42
-7
@@ -28,11 +28,11 @@
|
||||
#import <OpenEmuBase/OERingBuffer.h>
|
||||
#import <OpenGL/gl.h>
|
||||
|
||||
#include "gfx/OpenEmuGLContext.h"
|
||||
|
||||
#include "base/NativeApp.h"
|
||||
#include "base/timeutil.h"
|
||||
|
||||
#include "gfx/OpenEmuGLContext.h"
|
||||
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/CoreParameter.h"
|
||||
@@ -41,8 +41,10 @@
|
||||
#include "Core/Host.h"
|
||||
#include "Core/SaveState.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "Common/GraphicsContext.h"
|
||||
#include "Common/LogManager.h"
|
||||
|
||||
#include "thin3d/thin3d_create.h"
|
||||
#include "thin3d/GLRenderManager.h"
|
||||
#include "thin3d/DataFormatGL.h"
|
||||
@@ -53,6 +55,26 @@
|
||||
|
||||
|
||||
|
||||
namespace SaveState {
|
||||
struct SaveStart {
|
||||
void DoState(PointerWrap &p);
|
||||
};
|
||||
} // namespace SaveState
|
||||
|
||||
namespace OpenEmuCoreThread {
|
||||
enum class EmuThreadState {
|
||||
DISABLED,
|
||||
START_REQUESTED,
|
||||
RUNNING,
|
||||
PAUSE_REQUESTED,
|
||||
PAUSED,
|
||||
QUIT_REQUESTED,
|
||||
STOPPED,
|
||||
};
|
||||
} //namespace OpenEmuThreadCore
|
||||
|
||||
void NativeSetThreadState(OpenEmuCoreThread::EmuThreadState threadState);
|
||||
|
||||
@interface PPSSPPGameCore () <OEPSPSystemResponderClient, OEAudioBuffer>
|
||||
{
|
||||
CoreParameter _coreParam;
|
||||
@@ -65,6 +87,7 @@
|
||||
@end
|
||||
|
||||
PPSSPPGameCore *_current = 0;
|
||||
|
||||
@implementation PPSSPPGameCore
|
||||
|
||||
|
||||
@@ -107,7 +130,7 @@ PPSSPPGameCore *_current = 0;
|
||||
g_Config.flash0Directory = directoryString.fileSystemRepresentation;
|
||||
g_Config.internalDataDirectory = directoryString.fileSystemRepresentation;
|
||||
g_Config.iGPUBackend = (int)GPUBackend::OPENGL;
|
||||
|
||||
|
||||
_coreParam.cpuCore = CPUCore::JIT;
|
||||
_coreParam.gpuCore = GPUCORE_GLES;
|
||||
_coreParam.enableSound = true;
|
||||
@@ -149,7 +172,7 @@ PPSSPPGameCore *_current = 0;
|
||||
// This is where PPSSPP will look for ppge_atlas.zim
|
||||
NSString *resourcePath = [[[[self owner] bundle] resourcePath] stringByAppendingString:@"/"];
|
||||
|
||||
OEgraphicsContext = OpenEmuGLContext::CreateGraphicsContext(); //new OpenEmuGLContext();
|
||||
OEgraphicsContext = OpenEmuGLContext::CreateGraphicsContext();
|
||||
|
||||
NativeInit(0, nil, nil, resourcePath.fileSystemRepresentation, nil, false);
|
||||
|
||||
@@ -175,6 +198,10 @@ PPSSPPGameCore *_current = 0;
|
||||
|
||||
host->BootDone();
|
||||
host->UpdateDisassembly();
|
||||
|
||||
//Start the Emulator Thread
|
||||
NativeSetThreadState(OpenEmuCoreThread::EmuThreadState::START_REQUESTED);
|
||||
|
||||
} else {
|
||||
u64 cyclesBefore, cyclesAfter; //before and after timing marks to calculate a frame interval
|
||||
cyclesBefore = CoreTiming::GetTicks();
|
||||
@@ -249,20 +276,28 @@ static void _OESaveStateCallback(bool status, std::string message, void *cbUserD
|
||||
{
|
||||
void (^block)(BOOL, NSError *) = (__bridge_transfer void(^)(BOOL, NSError *))cbUserData;
|
||||
|
||||
//Unpause the EmuThread by requesting it to start again
|
||||
NativeSetThreadState(OpenEmuCoreThread::EmuThreadState::START_REQUESTED);
|
||||
|
||||
block(status, nil);
|
||||
}
|
||||
|
||||
- (void)saveStateToFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
|
||||
{
|
||||
SaveState::Save(fileName.fileSystemRepresentation, _OESaveStateCallback, (__bridge_retained void *)[block copy]);
|
||||
if(_isInitialized) SaveState::Process();
|
||||
if(_isInitialized)
|
||||
SaveState::Process();
|
||||
}
|
||||
|
||||
|
||||
- (void)loadStateFromFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
|
||||
{
|
||||
SaveState::Load(fileName.fileSystemRepresentation, _OESaveStateCallback, (__bridge_retained void *)[block copy]);
|
||||
if(_isInitialized) SaveState::Process();
|
||||
if(_isInitialized){
|
||||
//We need to pause our EmuThread so we don't try to process the save state in the middle of a Frame Render
|
||||
NativeSetThreadState(OpenEmuCoreThread::EmuThreadState::PAUSE_REQUESTED);
|
||||
|
||||
SaveState::Process();
|
||||
}
|
||||
}
|
||||
|
||||
# pragma mark - Input
|
||||
|
||||
Reference in New Issue
Block a user