mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-14 09:48:12 +07:00
Android: use best possible device frame rate (#8728)
* Android: use best possible device frame rate * Add support for devices with Android 6.0+ --------- Co-authored-by: vegeta1k95 <vfylfhby>
This commit is contained in:
@ -2,10 +2,16 @@ package com.unciv.app
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
|
import android.hardware.display.DisplayManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.opengl.GLSurfaceView
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.Surface
|
||||||
|
import android.view.SurfaceHolder
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
@ -59,11 +65,39 @@ open class AndroidLauncher : AndroidApplication() {
|
|||||||
|
|
||||||
setDeepLinkedGame(intent)
|
setDeepLinkedGame(intent)
|
||||||
|
|
||||||
addScreenObscuredListener((Gdx.graphics as AndroidGraphics).view)
|
val glView = (Gdx.graphics as AndroidGraphics).view as GLSurfaceView
|
||||||
|
|
||||||
|
addScreenObscuredListener(glView)
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||||
|
addScreenRefreshRateListener(glView)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addScreenObscuredListener(contentView: View) {
|
/** Request the best available device frame rate for
|
||||||
contentView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
* the game, as soon as OpenGL surface is created */
|
||||||
|
private fun addScreenRefreshRateListener(surfaceView: GLSurfaceView) {
|
||||||
|
surfaceView.holder.addCallback(object: SurfaceHolder.Callback {
|
||||||
|
override fun surfaceCreated(holder: SurfaceHolder) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
val modes = display?.supportedModes ?: return
|
||||||
|
val bestRefreshRate = modes.maxOf { it.refreshRate }
|
||||||
|
holder.surface.setFrameRate(bestRefreshRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT)
|
||||||
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
val display = windowManager.defaultDisplay
|
||||||
|
val modes = display?.supportedModes ?: return
|
||||||
|
val bestMode = modes.maxBy { it.refreshRate }
|
||||||
|
val params = window.attributes
|
||||||
|
params.preferredDisplayModeId = bestMode.modeId
|
||||||
|
window.attributes = params
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {}
|
||||||
|
override fun surfaceDestroyed(holder: SurfaceHolder) {}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addScreenObscuredListener(surfaceView: GLSurfaceView) {
|
||||||
|
surfaceView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||||
/** [onGlobalLayout] gets triggered not only when the [windowVisibleDisplayFrame][View.getWindowVisibleDisplayFrame] changes, but also on other things.
|
/** [onGlobalLayout] gets triggered not only when the [windowVisibleDisplayFrame][View.getWindowVisibleDisplayFrame] changes, but also on other things.
|
||||||
* So we need to check if that was actually the thing that changed. */
|
* So we need to check if that was actually the thing that changed. */
|
||||||
private var lastVisibleDisplayFrame: Rect? = null
|
private var lastVisibleDisplayFrame: Rect? = null
|
||||||
@ -73,18 +107,18 @@ open class AndroidLauncher : AndroidApplication() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val r = Rect()
|
val r = Rect()
|
||||||
contentView.getWindowVisibleDisplayFrame(r)
|
surfaceView.getWindowVisibleDisplayFrame(r)
|
||||||
if (r.equals(lastVisibleDisplayFrame)) return
|
if (r.equals(lastVisibleDisplayFrame)) return
|
||||||
lastVisibleDisplayFrame = r
|
lastVisibleDisplayFrame = r
|
||||||
|
|
||||||
val stage = (UncivGame.Current.screen as BaseScreen).stage
|
val stage = (UncivGame.Current.screen as BaseScreen).stage
|
||||||
|
|
||||||
val horizontalRatio = stage.width / contentView.width
|
val horizontalRatio = stage.width / surfaceView.width
|
||||||
val verticalRatio = stage.height / contentView.height
|
val verticalRatio = stage.height / surfaceView.height
|
||||||
|
|
||||||
val visibleStage = Rectangle(
|
val visibleStage = Rectangle(
|
||||||
r.left * horizontalRatio,
|
r.left * horizontalRatio,
|
||||||
(contentView.height - r.bottom) * verticalRatio, // Android coordinate system has the origin in the top left, while GDX uses bottom left
|
(surfaceView.height - r.bottom) * verticalRatio, // Android coordinate system has the origin in the top left, while GDX uses bottom left
|
||||||
r.width() * horizontalRatio,
|
r.width() * horizontalRatio,
|
||||||
r.height() * verticalRatio
|
r.height() * verticalRatio
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user