Set resolution and default background based on HMD type

This commit is contained in:
amwatson 2024-01-24 17:05:36 -06:00
parent 1044c78069
commit 50891ee8c2
5 changed files with 106 additions and 51 deletions

View file

@ -288,8 +288,19 @@ void Config::ReadValues() {
sdl2_config->GetInteger("Camera", "camera_outer_left_flip", 0);
// VR
VRSettings::values.vr_environment = VRSettings::values.extra_performance_mode_enabled ? 2 /* void environment */: sdl2_config->GetInteger(
"VR", "vr_environment", 1);
// Note: hmdType is not read as a preference. It is initialized here so that it can
// be used to determine per-hmd settings in the config
{
const std::string hmdTypeStr = VRSettings::GetHMDTypeStr();
LOG_INFO(Config, "HMD type: {}", hmdTypeStr.c_str());
VRSettings::values.hmd_type = VRSettings::HmdTypeFromStr(hmdTypeStr);
}
VRSettings::values.vr_environment = VRSettings::values.extra_performance_mode_enabled ?
static_cast<long>(VRSettings::VREnvironmentType::VOID) : sdl2_config->GetInteger(
"VR", "vr_environment",
static_cast<long>(VRSettings::values.hmd_type == VRSettings::HMDType::QUEST3 ?
VRSettings::VREnvironmentType::PASSTHROUGH : VRSettings::VREnvironmentType::VOID));
VRSettings::values.cpu_level =
VRSettings::values.extra_performance_mode_enabled ? XR_HIGHEST_CPU_PERF_LEVEL

View file

@ -15,7 +15,7 @@ License : Licensed under GPLv3 or any later version.
#include <android/log.h>
#include <stdlib.h>
#ifndef LOG_TAG
#define LOG_TAG "Citra::VR"
#define LOG_TAG "Citra::Input"
#endif
#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
@ -26,6 +26,7 @@ License : Licensed under GPLv3 or any later version.
#else
#define ALOGD(...)
#endif
#define FAIL(...) \
do { \
__android_log_print(ANDROID_LOG_FATAL, LOG_TAG, __VA_ARGS__); \

View file

@ -95,7 +95,7 @@ void ForwardButtonStateIfNeeded(JNIEnv* jni, jobject activityObject,
}
}
const char* XrSessionStateToString(const XrSessionState state) {
[[maybe_unused]] const char* XrSessionStateToString(const XrSessionState state) {
switch (state) {
case XR_SESSION_STATE_UNKNOWN:
return "XR_SESSION_STATE_UNKNOWN";
@ -122,34 +122,19 @@ const char* XrSessionStateToString(const XrSessionState state) {
}
}
enum class HMDType { UNKNOWN = 0, QUEST1, QUEST2, QUEST3, QUESTPRO };
HMDType StringToHmdType(const std::string& hmdType) {
if (hmdType == "Quest") {
return HMDType::QUEST1;
} else if (hmdType == "Quest" || hmdType == "Quest 2" || hmdType == "Miramar") {
return HMDType::QUEST2;
} else if (hmdType == "Quest 3") {
return HMDType::QUEST3;
} else if (hmdType == "Quest Pro") {
return HMDType::QUESTPRO;
}
return HMDType::UNKNOWN;
}
uint32_t GetDefaultGameResolutionFactorForHmd(const HMDType& hmdType) {
uint32_t GetDefaultGameResolutionFactorForHmd(const VRSettings::HMDType& hmdType) {
static constexpr uint32_t kDefaultResolutionFactor = 2;
switch (hmdType) {
case HMDType::QUEST3:
case VRSettings::HMDType::QUEST3:
return 3;
case HMDType::UNKNOWN:
case VRSettings::HMDType::UNKNOWN:
ALOGW("Warning: Unknown HMD type, using default scale factor of %d",
kDefaultResolutionFactor);
case HMDType::QUEST1:
case VRSettings::HMDType::QUEST1:
ALOGW("Warning: Unsupported HMD type, using default scale factor of %d",
kDefaultResolutionFactor);
case HMDType::QUEST2:
case HMDType::QUESTPRO:
case VRSettings::HMDType::QUEST2:
case VRSettings::HMDType::QUESTPRO:
return kDefaultResolutionFactor;
}
}
@ -201,19 +186,25 @@ public:
mInputStateStatic =
std::make_unique<InputStateStatic>(OpenXr::GetInstance(), gOpenXr->session_);
assert(VRSettings::values.vr_environment > 0 && VRSettings::values.vr_environment <= 2);
//////////////////////////////////////////////////
// Create the layers
//////////////////////////////////////////////////
// Create the background layer.
assert(VRSettings::values.vr_environment ==
static_cast<int32_t>(VRSettings::VREnvironmentType::VOID) ||
VRSettings::values.vr_environment ==
static_cast<int32_t>(VRSettings::VREnvironmentType::PASSTHROUGH));
// If user set "Void" in settings, don't render passthrough
if (VRSettings::values.vr_environment != 2) {
if (VRSettings::values.vr_environment !=
static_cast<int32_t>(VRSettings::VREnvironmentType::VOID)) {
mPassthroughLayer = std::make_unique<PassthroughLayer>(gOpenXr->session_);
}
mCursorLayer = std::make_unique<CursorLayer>(gOpenXr->session_);
{
const std::string hmdTypeStr =
SyspropUtils::GetSysPropAsString("ro.product.model", "unknown");
const HMDType hmdType = StringToHmdType(hmdTypeStr);
ALOGI("HMD type: %s (%d)", hmdTypeStr.c_str(), hmdType);
const uint32_t defaultResolutionFactor = GetDefaultGameResolutionFactorForHmd(hmdType);
// Create the game surface layer.
{
const uint32_t defaultResolutionFactor =
GetDefaultGameResolutionFactorForHmd(VRSettings::values.hmd_type);
const uint32_t resolutionFactorFromPreferences = VRSettings::values.resolution_factor;
const uint32_t resolutionFactor = resolutionFactorFromPreferences > 0
? resolutionFactorFromPreferences
@ -226,12 +217,19 @@ public:
XrVector3f{0, 0, -2.0f}, jni, mActivityObject, gOpenXr->session_, resolutionFactor);
}
// Create the cursor layer.
mCursorLayer = std::make_unique<CursorLayer>(gOpenXr->session_);
#if defined(UI_LAYER)
mErrorMessageLayer = std::make_unique<UILayer>("org/citra/citra_emu/vr/ErrorMessageLayer",
XrVector3f{0, 0, -0.7}, jni, mActivityObject,
gOpenXr->session_);
#endif
//////////////////////////////////////////////////
// Intialize JNI methods
//////////////////////////////////////////////////
mForwardVRInputMethodID =
jni->GetMethodID(jni->GetObjectClass(mActivityObject), "forwardVRInput", "(IZ)V");
if (mForwardVRInputMethodID == nullptr) {
@ -264,6 +262,10 @@ public:
FAIL("could not get openSettingsMenuMethodID");
}
//////////////////////////////////////////////////
// Frame loop
//////////////////////////////////////////////////
while (!mIsStopRequested) {
Frame(jni);
}
@ -806,7 +808,7 @@ private:
__func__);
break;
case XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT: {
const XrEventDataPerfSettingsEXT* pfs =
[[maybe_unused]] const XrEventDataPerfSettingsEXT* pfs =
(XrEventDataPerfSettingsEXT*)(baseEventHeader);
ALOGV("%s(): Received "
"XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT event: type %d "

View file

@ -1,8 +1,54 @@
/*******************************************************************************
Filename : vr_settings.cpp
Content : VR-specific settings initialized in config.cpp
Authors : Amanda M. Watson
License : Licensed under GPLv3 or any later version.
Refer to the license.txt file included.
*******************************************************************************/
#include "vr_settings.h"
namespace VRSettings {
#include "utils/LogUtils.h"
#include "utils/SyspropUtils.h"
#include <string>
namespace VRSettings {
Values values = {};
HMDType HmdTypeFromStr(const std::string& hmdType) {
if (hmdType == "Quest") {
return HMDType::QUEST1;
} else if (hmdType == "Quest" || hmdType == "Quest 2" || hmdType == "Miramar") {
return HMDType::QUEST2;
} else if (hmdType == "Quest 3") {
return HMDType::QUEST3;
} else if (hmdType == "Quest Pro") {
return HMDType::QUESTPRO;
}
return HMDType::UNKNOWN;
}
std::string GetHMDTypeStr() {
return SyspropUtils::GetSysPropAsString("ro.product.model", "Unknown");
}
XrPerfSettingsLevelEXT CPUPrefToPerfSettingsLevel(const int32_t cpu_level_pref) {
switch (cpu_level_pref) {
case 1:
return XR_PERF_SETTINGS_LEVEL_POWER_SAVINGS_EXT;
case 2:
return XR_PERF_SETTINGS_LEVEL_SUSTAINED_LOW_EXT;
case 3:
return XR_PERF_SETTINGS_LEVEL_SUSTAINED_HIGH_EXT;
case 4:
return XR_PERF_SETTINGS_LEVEL_BOOST_EXT;
default:
FAIL("Invalid CPU level preference %d", cpu_level_pref);
}
}
} // namespace VRSettings

View file

@ -15,7 +15,6 @@ License : Licensed under GPLv3 or any later version.
#pragma once
#include "OpenXR.h"
#include "utils/LogUtils.h"
#include <string>
@ -25,26 +24,22 @@ License : Licensed under GPLv3 or any later version.
namespace VRSettings {
static inline XrPerfSettingsLevelEXT CPUPrefToPerfSettingsLevel(const int32_t cpu_level_pref) {
switch (cpu_level_pref) {
case 1:
return XR_PERF_SETTINGS_LEVEL_POWER_SAVINGS_EXT;
case 2:
return XR_PERF_SETTINGS_LEVEL_SUSTAINED_LOW_EXT;
case 3:
return XR_PERF_SETTINGS_LEVEL_SUSTAINED_HIGH_EXT;
case 4:
return XR_PERF_SETTINGS_LEVEL_BOOST_EXT;
default:
FAIL("Invalid CPU level preference %d", cpu_level_pref);
}
}
enum class HMDType { UNKNOWN = 0, QUEST1, QUEST2, QUEST3, QUESTPRO };
enum class VREnvironmentType { PASSTHROUGH = 1, VOID = 2 };
// Given a CPU level preference, return the corresponding OpenXR performance level
XrPerfSettingsLevelEXT CPUPrefToPerfSettingsLevel(const int32_t cpu_level_pref);
// Return the HMD type as a string (queried from ro.product.model)
std::string GetHMDTypeStr();
// Given a string from GetHMDTypeStr(), return the corresponding HMDType
HMDType HmdTypeFromStr(const std::string& hmdType);
struct Values {
bool extra_performance_mode_enabled = false;
int32_t vr_environment = 0;
XrPerfSettingsLevelEXT cpu_level = XR_HIGHEST_CPU_PERF_LEVEL;
uint32_t resolution_factor = 0;
HMDType hmd_type = HMDType::UNKNOWN;
} extern values;
} // namespace VRSettings