mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2025-12-16 03:58:42 +00:00
android: Force app to use max available refresh rate in menus (#1492)
* [android]: Force app to use the displays max set refresh rate Since Android 15, google automatically forces "games" to be 60 hrz. This ensures the display's max refresh rate is actually used. Tested on a Google Pixel 7 Pro with Android 16 Emulation Activity was excluded for battery usage concerns * force60Hrz option * Code cleanup * Expanded refresh rate explaination comment * Moved `enforceRefreshRate` calls to earlier in `onCreate` This probably doesn't actually do anything, it's a bit of a nitpick * Moved `enforceRefreshRate` SDK version check to within the function --------- Co-authored-by: OpenSauce04 <opensauce04@gmail.com>
This commit is contained in:
parent
b0fe4d190d
commit
6b05944116
@ -10,6 +10,7 @@ import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.InputDevice
|
||||
import android.view.KeyEvent
|
||||
@ -47,6 +48,7 @@ import org.citra.citra_emu.utils.FileBrowserHelper
|
||||
import org.citra.citra_emu.utils.EmulationLifecycleUtil
|
||||
import org.citra.citra_emu.utils.EmulationMenuSettings
|
||||
import org.citra.citra_emu.utils.Log
|
||||
import org.citra.citra_emu.utils.RefreshRateUtil
|
||||
import org.citra.citra_emu.utils.ThemeUtil
|
||||
import org.citra.citra_emu.viewmodel.EmulationViewModel
|
||||
|
||||
@ -82,6 +84,8 @@ class EmulationActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
|
||||
RefreshRateUtil.enforceRefreshRate(this, sixtyHz = true)
|
||||
|
||||
ThemeUtil.setTheme(this)
|
||||
settingsViewModel.settings.loadSettings()
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@ -7,6 +7,7 @@ package org.citra.citra_emu.features.settings.ui
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.MarginLayoutParams
|
||||
@ -37,6 +38,7 @@ import org.citra.citra_emu.features.settings.utils.SettingsFile
|
||||
import org.citra.citra_emu.utils.SystemSaveGame
|
||||
import org.citra.citra_emu.utils.DirectoryInitialization
|
||||
import org.citra.citra_emu.utils.InsetsHelper
|
||||
import org.citra.citra_emu.utils.RefreshRateUtil
|
||||
import org.citra.citra_emu.utils.ThemeUtil
|
||||
|
||||
class SettingsActivity : AppCompatActivity(), SettingsActivityView {
|
||||
@ -49,6 +51,8 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
|
||||
override val settings: Settings get() = settingsViewModel.settings
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
RefreshRateUtil.enforceRefreshRate(this)
|
||||
|
||||
ThemeUtil.setTheme(this)
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@ -6,6 +6,7 @@ package org.citra.citra_emu.ui.main
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.MarginLayoutParams
|
||||
@ -51,6 +52,7 @@ import org.citra.citra_emu.utils.CitraDirectoryUtils
|
||||
import org.citra.citra_emu.utils.DirectoryInitialization
|
||||
import org.citra.citra_emu.utils.FileBrowserHelper
|
||||
import org.citra.citra_emu.utils.InsetsHelper
|
||||
import org.citra.citra_emu.utils.RefreshRateUtil
|
||||
import org.citra.citra_emu.utils.PermissionsHandler
|
||||
import org.citra.citra_emu.utils.ThemeUtil
|
||||
import org.citra.citra_emu.viewmodel.GamesViewModel
|
||||
@ -66,6 +68,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||
override var themeId: Int = 0
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
RefreshRateUtil.enforceRefreshRate(this)
|
||||
|
||||
val splashScreen = installSplashScreen()
|
||||
CitraDirectoryUtils.attemptAutomaticUpdateDirectory()
|
||||
splashScreen.setKeepOnScreenCondition {
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
package org.citra.citra_emu.utils
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
object RefreshRateUtil {
|
||||
// Since Android 15, the OS automatically runs apps categorized as games with a
|
||||
// 60hz refresh rate by default, regardless of the refresh rate set by the user.
|
||||
//
|
||||
// This function sets the refresh rate to either the maximum allowed refresh rate or
|
||||
// 60hz depending on the value of the `sixtyHz` parameter.
|
||||
//
|
||||
// Note: This isn't always the maximum refresh rate that the display is *capable of*,
|
||||
// but is instead the refresh rate chosen by the user in the Android system settings.
|
||||
// For example, if the user selected 120hz in the settings, but the display is capable
|
||||
// of 144hz, 120hz will be treated as the maximum within this function.
|
||||
fun enforceRefreshRate(activity: Activity, sixtyHz: Boolean = false) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||
return
|
||||
}
|
||||
|
||||
val display = activity.display
|
||||
val window = activity.window
|
||||
|
||||
display?.let {
|
||||
// Get all supported modes and find the one with the highest refresh rate
|
||||
val supportedModes = it.supportedModes
|
||||
val maxRefreshRate = supportedModes.maxByOrNull { mode -> mode.refreshRate }
|
||||
|
||||
if (maxRefreshRate == null) {
|
||||
return
|
||||
}
|
||||
|
||||
var newModeId: Int?
|
||||
if (sixtyHz) {
|
||||
newModeId = supportedModes.firstOrNull { mode -> mode.refreshRate == 60f }?.modeId
|
||||
} else {
|
||||
// Set the preferred display mode to the one with the highest refresh rate
|
||||
newModeId = maxRefreshRate.modeId
|
||||
}
|
||||
|
||||
if (newModeId == null) {
|
||||
return
|
||||
}
|
||||
|
||||
window.attributes.preferredDisplayModeId = newModeId
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user