mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-29 15:45:29 +03:00
Support forcing 60Hz display on Xiaomi MIUI
Uses an API found through RE since none of the AOSP APIs work, additionaly the code for setting RR was consolidated to a single function that can be ran after all display updates.
This commit is contained in:
parent
42c365fe70
commit
b75a06af1b
@ -10,11 +10,13 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.AssetManager
|
import android.content.res.AssetManager
|
||||||
import android.graphics.PointF
|
import android.graphics.PointF
|
||||||
|
import android.hardware.display.DisplayManager
|
||||||
import android.os.*
|
import android.os.*
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.Rational
|
import android.util.Rational
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isInvisible
|
import androidx.core.view.isInvisible
|
||||||
import androidx.core.view.updateMargins
|
import androidx.core.view.updateMargins
|
||||||
@ -27,8 +29,9 @@ import java.io.File
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTouchListener {
|
class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTouchListener, DisplayManager.DisplayListener {
|
||||||
companion object {
|
companion object {
|
||||||
private val Tag = EmulationActivity::class.java.simpleName
|
private val Tag = EmulationActivity::class.java.simpleName
|
||||||
val ReturnToMainTag = "returnToMain"
|
val ReturnToMainTag = "returnToMain"
|
||||||
@ -178,6 +181,26 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
|||||||
updateControllers()
|
updateControllers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces a 60Hz refresh rate for the primary display when [enable] is true, otherwise selects the highest available refresh rate
|
||||||
|
*/
|
||||||
|
private fun force60HzRefreshRate(enable : Boolean) {
|
||||||
|
// Hack for MIUI devices since they don't support the standard Android APIs
|
||||||
|
try {
|
||||||
|
val setFpsIntent = Intent("com.miui.powerkeeper.SET_ACTIVITY_FPS")
|
||||||
|
setFpsIntent.putExtra("package_name", "skyline.emu")
|
||||||
|
setFpsIntent.putExtra("isEnter", enable)
|
||||||
|
sendBroadcast(setFpsIntent)
|
||||||
|
} catch (_ : Exception) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION") val display = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) display!! else windowManager.defaultDisplay
|
||||||
|
if (enable)
|
||||||
|
display?.supportedModes?.minByOrNull { abs(it.refreshRate - 60f) }?.let { window.attributes.preferredDisplayModeId = it.modeId }
|
||||||
|
else
|
||||||
|
display?.supportedModes?.maxByOrNull { it.refreshRate }?.let { window.attributes.preferredDisplayModeId = it.modeId }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return from emulation to either [MainActivity] or the activity on the back stack
|
* Return from emulation to either [MainActivity] or the activity on the back stack
|
||||||
*/
|
*/
|
||||||
@ -275,12 +298,8 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION") val display = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) display!! else windowManager.defaultDisplay
|
force60HzRefreshRate(!settings.maxRefreshRate)
|
||||||
if (settings.maxRefreshRate) {
|
getSystemService<DisplayManager>()?.registerDisplayListener(this, null)
|
||||||
display?.supportedModes?.maxByOrNull { it.refreshRate * it.physicalHeight * it.physicalWidth }?.let { window.attributes.preferredDisplayModeId = it.modeId; desiredRefreshRate = it.refreshRate }
|
|
||||||
} else {
|
|
||||||
display?.supportedModes?.minByOrNull { abs(it.refreshRate - 60f) }?.let { window.attributes.preferredDisplayModeId = it.modeId }
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.gameView.setOnTouchListener(this)
|
binding.gameView.setOnTouchListener(this)
|
||||||
|
|
||||||
@ -343,6 +362,10 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
|||||||
stopEmulation(false)
|
stopEmulation(false)
|
||||||
vibrators.forEach { (_, vibrator) -> vibrator.cancel() }
|
vibrators.forEach { (_, vibrator) -> vibrator.cancel() }
|
||||||
vibrators.clear()
|
vibrators.clear()
|
||||||
|
|
||||||
|
// Stop forcing 60Hz on exit to allow the skyline UI to run at high refresh rates
|
||||||
|
getSystemService<DisplayManager>()?.unregisterDisplayListener(this)
|
||||||
|
force60HzRefreshRate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun surfaceCreated(holder : SurfaceHolder) {
|
override fun surfaceCreated(holder : SurfaceHolder) {
|
||||||
@ -573,4 +596,14 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
|||||||
}
|
}
|
||||||
insets
|
insets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDisplayChanged(displayId : Int) {
|
||||||
|
val display = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) display!! else windowManager.defaultDisplay
|
||||||
|
if (display.displayId == displayId)
|
||||||
|
force60HzRefreshRate(!settings.maxRefreshRate)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDisplayAdded(displayId : Int) {}
|
||||||
|
|
||||||
|
override fun onDisplayRemoved(displayId : Int) {}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user