|
|
|
@@ -63,6 +63,7 @@
|
|
|
|
|
|
|
|
|
|
#include "jni/AndroidCommon/AndroidCommon.h"
|
|
|
|
|
#include "jni/AndroidCommon/IDCache.h"
|
|
|
|
|
#include "jni/Host.h"
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
@@ -70,25 +71,6 @@ constexpr char DOLPHIN_TAG[] = "DolphinEmuNative";
|
|
|
|
|
|
|
|
|
|
ANativeWindow* s_surf;
|
|
|
|
|
|
|
|
|
|
// The Core only supports using a single Host thread.
|
|
|
|
|
// If multiple threads want to call host functions then they need to queue
|
|
|
|
|
// sequentially for access.
|
|
|
|
|
std::mutex s_host_identity_lock;
|
|
|
|
|
template <typename T>
|
|
|
|
|
struct HostThreadWrapper
|
|
|
|
|
{
|
|
|
|
|
T lock;
|
|
|
|
|
|
|
|
|
|
explicit HostThreadWrapper(auto&&... args) : lock(std::forward<decltype(args)>(args)...)
|
|
|
|
|
{
|
|
|
|
|
Core::DeclareAsHostThread();
|
|
|
|
|
}
|
|
|
|
|
HostThreadWrapper(const HostThreadWrapper& other) = delete;
|
|
|
|
|
HostThreadWrapper(HostThreadWrapper&& other) = delete;
|
|
|
|
|
HostThreadWrapper& operator=(const HostThreadWrapper& other) = delete;
|
|
|
|
|
HostThreadWrapper& operator=(HostThreadWrapper&& other) = delete;
|
|
|
|
|
~HostThreadWrapper() { Core::UndeclareAsHostThread(); }
|
|
|
|
|
};
|
|
|
|
|
Common::Event s_update_main_frame_event;
|
|
|
|
|
|
|
|
|
|
// This exists to prevent surfaces from being destroyed during the boot process,
|
|
|
|
@@ -263,19 +245,19 @@ extern "C" {
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_UnPauseEmulation(JNIEnv*,
|
|
|
|
|
jclass)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
Core::SetState(Core::State::Running);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulation(JNIEnv*, jclass)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
Core::SetState(Core::State::Paused);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv*, jclass)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
Core::Stop();
|
|
|
|
|
|
|
|
|
|
// Kick the waiting event
|
|
|
|
@@ -318,7 +300,7 @@ JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetGitRev
|
|
|
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveScreenShot(JNIEnv*, jclass)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
Core::SaveScreenShot();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -332,7 +314,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveState(JN
|
|
|
|
|
jint slot,
|
|
|
|
|
jboolean wait)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
State::Save(slot, wait);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -340,21 +322,21 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveStateAs(
|
|
|
|
|
jstring path,
|
|
|
|
|
jboolean wait)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
State::SaveAs(GetJString(env, path), wait);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadState(JNIEnv*, jclass,
|
|
|
|
|
jint slot)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
State::Load(slot);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadStateAs(JNIEnv* env, jclass,
|
|
|
|
|
jstring path)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
State::LoadAs(GetJString(env, path));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -383,7 +365,7 @@ Java_org_dolphinemu_dolphinemu_utils_DirectoryInitialization_SetGpuDriverDirecto
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserDirectory(
|
|
|
|
|
JNIEnv* env, jclass, jstring jDirectory)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
UICommon::SetUserDirectory(GetJString(env, jDirectory));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -396,7 +378,7 @@ JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserDi
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetCacheDirectory(
|
|
|
|
|
JNIEnv* env, jclass, jstring jDirectory)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
File::SetUserPath(D_CACHE_IDX, GetJString(env, jDirectory));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -419,7 +401,7 @@ JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetMaxLogLev
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfiling(JNIEnv*, jclass,
|
|
|
|
|
jboolean enable)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
Core::SetState(Core::State::Paused);
|
|
|
|
|
auto& jit_interface = Core::System::GetInstance().GetJitInterface();
|
|
|
|
|
jit_interface.ClearCache();
|
|
|
|
@@ -431,7 +413,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfiling
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_WriteProfileResults(JNIEnv*,
|
|
|
|
|
jclass)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
std::string filename = File::GetUserPath(D_DUMP_IDX) + "Debug/profiler.txt";
|
|
|
|
|
File::CreateFullPath(filename);
|
|
|
|
|
auto& jit_interface = Core::System::GetInstance().GetJitInterface();
|
|
|
|
@@ -460,14 +442,14 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestr
|
|
|
|
|
// If emulation continues running without a valid surface, we will probably crash,
|
|
|
|
|
// so pause emulation until we get a valid surface again. EmulationFragment handles resuming.
|
|
|
|
|
|
|
|
|
|
HostThreadWrapper<std::unique_lock<std::mutex>> host_identity_guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock host_identity_guard;
|
|
|
|
|
|
|
|
|
|
while (s_is_booting.IsSet())
|
|
|
|
|
{
|
|
|
|
|
// Need to wait for boot to finish before we can pause
|
|
|
|
|
host_identity_guard.lock.unlock();
|
|
|
|
|
host_identity_guard.m_lock.unlock();
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
|
|
|
host_identity_guard.lock.lock();
|
|
|
|
|
host_identity_guard.m_lock.lock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Core::GetState() == Core::State::Running)
|
|
|
|
@@ -501,7 +483,7 @@ JNIEXPORT jfloat JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetGameAsp
|
|
|
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_RefreshWiimotes(JNIEnv*, jclass)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::lock_guard<std::mutex>> guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock guard;
|
|
|
|
|
WiimoteReal::Refresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -559,7 +541,7 @@ static float GetRenderSurfaceScale(JNIEnv* env)
|
|
|
|
|
|
|
|
|
|
static void Run(JNIEnv* env, std::unique_ptr<BootParameters>&& boot, bool riivolution)
|
|
|
|
|
{
|
|
|
|
|
HostThreadWrapper<std::unique_lock<std::mutex>> host_identity_guard(s_host_identity_lock);
|
|
|
|
|
HostThreadLock host_identity_guard;
|
|
|
|
|
|
|
|
|
|
if (riivolution && std::holds_alternative<BootParameters::Disc>(boot->parameters))
|
|
|
|
|
{
|
|
|
|
@@ -590,15 +572,15 @@ static void Run(JNIEnv* env, std::unique_ptr<BootParameters>&& boot, bool riivol
|
|
|
|
|
|
|
|
|
|
while (Core::IsRunning())
|
|
|
|
|
{
|
|
|
|
|
host_identity_guard.lock.unlock();
|
|
|
|
|
host_identity_guard.m_lock.unlock();
|
|
|
|
|
s_update_main_frame_event.Wait();
|
|
|
|
|
host_identity_guard.lock.lock();
|
|
|
|
|
host_identity_guard.m_lock.lock();
|
|
|
|
|
Core::HostDispatchJobs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s_game_metadata_is_valid = false;
|
|
|
|
|
Core::Shutdown();
|
|
|
|
|
host_identity_guard.lock.unlock();
|
|
|
|
|
host_identity_guard.m_lock.unlock();
|
|
|
|
|
|
|
|
|
|
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(),
|
|
|
|
|
IDCache::GetFinishEmulationActivity());
|
|
|
|
|