Fix KtSettings JNI usage

* Use a global ref for NativeSettings JNI instance
* Always use the JNI env from the JNI call to ensure it's safe to use in the current thread
This commit is contained in:
lynxnb 2023-02-06 19:41:57 +01:00 committed by Billy Laws
parent 5b0a397165
commit fc9b34846c
4 changed files with 16 additions and 12 deletions

View File

@ -27,7 +27,7 @@ std::weak_ptr<skyline::kernel::OS> OsWeak;
std::weak_ptr<skyline::gpu::GPU> GpuWeak; std::weak_ptr<skyline::gpu::GPU> GpuWeak;
std::weak_ptr<skyline::audio::Audio> AudioWeak; std::weak_ptr<skyline::audio::Audio> AudioWeak;
std::weak_ptr<skyline::input::Input> InputWeak; std::weak_ptr<skyline::input::Input> InputWeak;
std::weak_ptr<skyline::Settings> SettingsWeak; std::weak_ptr<skyline::AndroidSettings> SettingsWeak;
// https://cs.android.com/android/platform/superproject/+/master:bionic/libc/tzcode/bionic.cpp;l=43;drc=master;bpv=1;bpt=1 // https://cs.android.com/android/platform/superproject/+/master:bionic/libc/tzcode/bionic.cpp;l=43;drc=master;bpv=1;bpt=1
static std::string GetTimeZoneName() { static std::string GetTimeZoneName() {
@ -85,7 +85,8 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
auto jvmManager{std::make_shared<skyline::JvmManager>(env, instance)}; auto jvmManager{std::make_shared<skyline::JvmManager>(env, instance)};
std::shared_ptr<skyline::Settings> settings{std::make_shared<skyline::AndroidSettings>(env, settingsInstance)}; auto androidSettings{std::make_shared<skyline::AndroidSettings>(env, settingsInstance)};
std::shared_ptr<skyline::Settings> settings{androidSettings};
skyline::JniString publicAppFilesPath(env, publicAppFilesPathJstring); skyline::JniString publicAppFilesPath(env, publicAppFilesPathJstring);
skyline::Logger::EmulationContext.Initialize(publicAppFilesPath + "logs/emulation.sklog"); skyline::Logger::EmulationContext.Initialize(publicAppFilesPath + "logs/emulation.sklog");
@ -115,7 +116,7 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
GpuWeak = os->state.gpu; GpuWeak = os->state.gpu;
AudioWeak = os->state.audio; AudioWeak = os->state.audio;
InputWeak = os->state.input; InputWeak = os->state.input;
SettingsWeak = settings; SettingsWeak = androidSettings;
jvmManager->InitializeControllers(); jvmManager->InitializeControllers();
skyline::Logger::DebugNoPrefix("Launching ROM {}", skyline::JniString(env, romUriJstring)); skyline::Logger::DebugNoPrefix("Launching ROM {}", skyline::JniString(env, romUriJstring));
@ -247,6 +248,7 @@ extern "C" JNIEXPORT void JNICALL Java_emu_skyline_utils_NativeSettings_updateNa
auto settings{SettingsWeak.lock()}; auto settings{SettingsWeak.lock()};
if (!settings) if (!settings)
return; // We don't mind if we miss settings updates while settings haven't been initialized return; // We don't mind if we miss settings updates while settings haven't been initialized
settings->BeginTransaction(env);
settings->Update(); settings->Update();
} }

View File

@ -20,14 +20,12 @@ namespace skyline {
* @note Will construct the underlying KtSettings object in-place * @note Will construct the underlying KtSettings object in-place
*/ */
AndroidSettings(JNIEnv *env, jobject settingsInstance) : ktSettings(env, settingsInstance) { AndroidSettings(JNIEnv *env, jobject settingsInstance) : ktSettings(env, settingsInstance) {
ktSettings.BeginTransaction(env);
Update(); Update();
} }
/** void BeginTransaction(JNIEnv *env) {
* @note Will take ownership of the passed KtSettings object ktSettings.BeginTransaction(env);
*/
AndroidSettings(KtSettings &&ktSettings) : ktSettings(std::move(ktSettings)) {
Update();
} }
void Update() override { void Update() override {
@ -50,6 +48,6 @@ namespace skyline {
disableSubgroupShuffle = ktSettings.GetBool("disableSubgroupShuffle"); disableSubgroupShuffle = ktSettings.GetBool("disableSubgroupShuffle");
isAudioOutputDisabled = ktSettings.GetBool("isAudioOutputDisabled"); isAudioOutputDisabled = ktSettings.GetBool("isAudioOutputDisabled");
validationLayer = ktSettings.GetBool("validationLayer"); validationLayer = ktSettings.GetBool("validationLayer");
}; }
}; };
} }

View File

@ -33,7 +33,7 @@ namespace skyline::gpu {
auto desc{presentationTrack.Serialize()}; auto desc{presentationTrack.Serialize()};
desc.set_name("Presentation"); desc.set_name("Presentation");
perfetto::TrackEvent::SetTrackDescriptor(presentationTrack, desc); perfetto::TrackEvent::SetTrackDescriptor(presentationTrack, desc);
state.settings->disableFrameThrottling.AddCallback(std::bind(&PresentationEngine::OnDisableFrameThrottlingChanged, this, std::placeholders::_1)); state.settings->disableFrameThrottling.AddCallback([this](auto && value) { OnDisableFrameThrottlingChanged(value); });
} }
PresentationEngine::~PresentationEngine() { PresentationEngine::~PresentationEngine() {

View File

@ -25,12 +25,12 @@ namespace skyline {
*/ */
class KtSettings { class KtSettings {
private: private:
JNIEnv *env; //!< A pointer to the current jni environment JNIEnv *env{}; //!< The JNI environment
jclass settingsClass; //!< The settings class jclass settingsClass; //!< The settings class
jobject settingsInstance; //!< The settings instance jobject settingsInstance; //!< The settings instance
public: public:
KtSettings(JNIEnv *env, jobject settingsInstance) : env(env), settingsInstance(settingsInstance), settingsClass(env->GetObjectClass(settingsInstance)) {} KtSettings(JNIEnv *env, jobject settingsInstance) : settingsInstance(env->NewGlobalRef(settingsInstance)), settingsClass(reinterpret_cast<jclass>(env->NewGlobalRef(env->GetObjectClass(settingsInstance)))) {}
KtSettings(const KtSettings &) = delete; KtSettings(const KtSettings &) = delete;
@ -38,6 +38,10 @@ namespace skyline {
KtSettings(KtSettings &&) = default; KtSettings(KtSettings &&) = default;
void BeginTransaction(JNIEnv *pEnv) {
this->env = pEnv;
}
/** /**
* @param key A null terminated string containing the key of the setting to get * @param key A null terminated string containing the key of the setting to get
*/ */