1
0
forked from MeloNX/MeloNX

android - add performance monitor

android - update dependencies

android - set isStarted check early

android - add performance stats

android - close file handles in performance monitor
This commit is contained in:
Emmanuel Hansen 2024-02-25 22:06:54 +00:00
parent 896851e909
commit d40dc00769
9 changed files with 139 additions and 36 deletions

View File

@ -5,14 +5,14 @@ plugins {
android { android {
namespace 'org.ryujinx.android' namespace 'org.ryujinx.android'
compileSdk 33 compileSdk 34
defaultConfig { defaultConfig {
applicationId "org.ryujinx.android" applicationId "org.ryujinx.android"
minSdk 30 minSdk 30
targetSdk 33 targetSdk 34
versionCode 10010 versionCode 10026
versionName '1.0.10' versionName '1.0.26t'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { vectorDrawables {
@ -52,7 +52,7 @@ android {
buildConfig true buildConfig true
} }
composeOptions { composeOptions {
kotlinCompilerExtensionVersion '1.3.2' kotlinCompilerExtensionVersion '1.5.2'
} }
packagingOptions { packagingOptions {
jniLibs { jniLibs {
@ -77,17 +77,17 @@ tasks.named("preBuild") {
dependencies { dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0' implementation 'com.google.android.material:material:1.11.0'
implementation platform('androidx.compose:compose-bom:2023.03.00') implementation platform('androidx.compose:compose-bom:2023.03.00')
implementation platform('androidx.compose:compose-bom:2023.03.00') implementation platform('androidx.compose:compose-bom:2023.03.00')
androidTestImplementation platform('androidx.compose:compose-bom:2023.03.00') androidTestImplementation platform('androidx.compose:compose-bom:2023.03.00')
androidTestImplementation platform('androidx.compose:compose-bom:2023.03.00') androidTestImplementation platform('androidx.compose:compose-bom:2023.03.00')
runtimeOnly project(":libryujinx") runtimeOnly project(":libryujinx")
implementation 'androidx.core:core-ktx:1.10.1' implementation 'androidx.core:core-ktx:1.12.0'
implementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0') implementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0')
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
implementation "androidx.navigation:navigation-compose:2.6.0" implementation "androidx.navigation:navigation-compose:2.7.6"
implementation 'androidx.activity:activity-compose:1.7.2' implementation 'androidx.activity:activity-compose:1.8.2'
implementation platform('androidx.compose:compose-bom:2023.06.00') implementation platform('androidx.compose:compose-bom:2023.06.00')
implementation 'androidx.compose.ui:ui' implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.ui:ui-graphics' implementation 'androidx.compose.ui:ui-graphics'
@ -96,12 +96,15 @@ dependencies {
implementation 'com.github.swordfish90:radialgamepad:2.0.0' implementation 'com.github.swordfish90:radialgamepad:2.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "com.anggrayudi:storage:1.5.5" implementation "com.anggrayudi:storage:1.5.5"
implementation "androidx.preference:preference-ktx:1.2.0" implementation "androidx.preference:preference-ktx:1.2.1"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2'
implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.google.code.gson:gson:2.10.1'
implementation 'net.lingala.zip4j:zip4j:2.11.5' implementation 'net.lingala.zip4j:zip4j:2.11.5'
implementation("br.com.devsrsouza.compose.icons:css-gg:1.1.0") implementation("br.com.devsrsouza.compose.icons:css-gg:1.1.0")
implementation "io.coil-kt:coil-compose:2.4.0" implementation "io.coil-kt:coil-compose:2.4.0"
implementation("com.halilibo.compose-richtext:richtext-ui:0.20.0")
implementation("com.halilibo.compose-richtext:richtext-commonmark:0.20.0")
implementation("com.halilibo.compose-richtext:richtext-ui-material3:0.20.0")
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

View File

@ -85,6 +85,8 @@ class GameHost(context: Context?, private val mainViewModel: MainViewModel) : Su
if (_isStarted) if (_isStarted)
return return
_isStarted = true
game = if (mainViewModel.isMiiEditorLaunched) null else mainViewModel.gameModel; game = if (mainViewModel.isMiiEditorLaunched) null else mainViewModel.gameModel;
_nativeRyujinx.inputInitialize(width, height) _nativeRyujinx.inputInitialize(width, height)
@ -102,7 +104,6 @@ class GameHost(context: Context?, private val mainViewModel: MainViewModel) : Su
_guestThread = thread(start = true) { _guestThread = thread(start = true) {
runGame() runGame()
} }
_isStarted = true
_updateThread = thread(start = true) { _updateThread = thread(start = true) {
var c = 0 var c = 0

View File

@ -18,7 +18,6 @@ import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.WindowInsetsControllerCompat
import com.anggrayudi.storage.SimpleStorageHelper import com.anggrayudi.storage.SimpleStorageHelper
import com.halilibo.richtext.ui.RichTextThemeIntegration
import org.ryujinx.android.ui.theme.RyujinxAndroidTheme import org.ryujinx.android.ui.theme.RyujinxAndroidTheme
import org.ryujinx.android.viewmodels.MainViewModel import org.ryujinx.android.viewmodels.MainViewModel
import org.ryujinx.android.viewmodels.QuickSettings import org.ryujinx.android.viewmodels.QuickSettings
@ -38,6 +37,7 @@ class MainActivity : BaseActivity() {
var mainViewModel: MainViewModel? = null var mainViewModel: MainViewModel? = null
var AppPath : String = "" var AppPath : String = ""
var StorageHelper: SimpleStorageHelper? = null var StorageHelper: SimpleStorageHelper? = null
val performanceMonitor = PerformanceMonitor()
@JvmStatic @JvmStatic
fun updateRenderSessionPerformance(gameTime : Long) fun updateRenderSessionPerformance(gameTime : Long)
@ -111,7 +111,6 @@ class MainActivity : BaseActivity() {
mainViewModel?.apply { mainViewModel?.apply {
setContent { setContent {
RyujinxAndroidTheme { RyujinxAndroidTheme {
RichTextThemeIntegration(contentColor = { MaterialTheme.colorScheme.onSurface }) {
// A surface container using the 'background' color from the theme // A surface container using the 'background' color from the theme
Surface( Surface(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
@ -123,7 +122,6 @@ class MainActivity : BaseActivity() {
} }
} }
} }
}
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
storageHelper?.onSaveInstanceState(outState) storageHelper?.onSaveInstanceState(outState)

View File

@ -0,0 +1,90 @@
package org.ryujinx.android
import android.app.ActivityManager
import android.content.Context.ACTIVITY_SERVICE
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import java.io.RandomAccessFile
class PerformanceMonitor {
val numberOfCores = Runtime.getRuntime().availableProcessors()
fun getFrequencies() : List<Double> {
val frequencies = mutableListOf<Double>()
for (i in 0..<numberOfCores){
var freq = 0.0;
try {
val reader = RandomAccessFile(
"/sys/devices/system/cpu/cpu${i}/cpufreq/scaling_cur_freq",
"r"
)
val f = reader.readLine()
reader.close()
freq = f.toDouble() / 1000.0
}
catch (e:Exception){
}
frequencies.add(freq)
}
return frequencies.toList()
}
fun getMemoryUsage() : List<Int> {
val mem = mutableListOf<Int>()
MainActivity.mainViewModel?.activity?.apply {
val actManager = getSystemService(ACTIVITY_SERVICE) as ActivityManager
val memInfo = ActivityManager.MemoryInfo()
actManager.getMemoryInfo(memInfo)
val availMemory = memInfo.availMem.toDouble()/(1024*1024)
val totalMemory= memInfo.totalMem.toDouble()/(1024*1024)
mem.add((totalMemory - availMemory).toInt())
mem.add(totalMemory.toInt())
}
return mem.toList()
}
@Composable
fun RenderUsage() {
LazyColumn{
val frequencies = getFrequencies()
val mem = getMemoryUsage()
for (i in 0..<numberOfCores){
item {
Row {
Text(modifier = Modifier.padding(2.dp), text = "CPU ${i}")
Spacer(Modifier.weight(1f))
Text(text = "${frequencies[i]} MHz")
}
}
}
if(mem.isNotEmpty()) {
item {
Row {
Text(modifier = Modifier.padding(2.dp), text = "Used")
Spacer(Modifier.weight(1f))
Text(text = "${mem[0]} MB")
}
}
item {
Row {
Text(modifier = Modifier.padding(2.dp), text = "Total")
Spacer(Modifier.weight(1f))
Text(text = "${mem[1]} MB")
}
}
}
}
}
}

View File

@ -29,7 +29,7 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import com.halilibo.richtext.markdown.Markdown import com.halilibo.richtext.markdown.Markdown
import com.halilibo.richtext.ui.RichText import com.halilibo.richtext.ui.material3.RichText
internal enum class KeyboardMode { internal enum class KeyboardMode {
Default, Numeric, ASCII, FullLatin, Alphabet, SimplifiedChinese, TraditionalChinese, Korean, LanguageSet2, LanguageSet2Latin Default, Numeric, ASCII, FullLatin, Alphabet, SimplifiedChinese, TraditionalChinese, Korean, LanguageSet2, LanguageSet2Latin

View File

@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
@ -18,11 +19,13 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Switch import androidx.compose.material3.Switch
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -30,7 +33,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.PointerEventType import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Popup import androidx.compose.ui.window.Popup
import compose.icons.CssGgIcons import compose.icons.CssGgIcons
@ -197,8 +202,10 @@ class GameViews {
mainViewModel.motionSensorManager?.unregister() mainViewModel.motionSensorManager?.unregister()
}) })
} }
Row(modifier = Modifier.padding(8.dp), Row(
horizontalArrangement = Arrangement.SpaceBetween) { modifier = Modifier.padding(8.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
IconButton(modifier = Modifier.padding(4.dp), onClick = { IconButton(modifier = Modifier.padding(4.dp), onClick = {
showMore.value = false showMore.value = false
showController.value = !showController.value showController.value = !showController.value
@ -338,6 +345,7 @@ class GameViews {
modifier = Modifier.padding(16.dp), modifier = Modifier.padding(16.dp),
color = MaterialTheme.colorScheme.background.copy(0.4f) color = MaterialTheme.colorScheme.background.copy(0.4f)
) { ) {
CompositionLocalProvider(LocalTextStyle provides TextStyle(fontSize = 10.sp)) {
Column { Column {
var gameTimeVal = 0.0 var gameTimeVal = 0.0
if (!gameTime.value.isInfinite()) if (!gameTime.value.isInfinite())
@ -345,6 +353,10 @@ class GameViews {
Text(text = "${String.format("%.3f", fifo.value)} %") Text(text = "${String.format("%.3f", fifo.value)} %")
Text(text = "${String.format("%.3f", gameFps.value)} FPS") Text(text = "${String.format("%.3f", gameFps.value)} FPS")
Text(text = "${String.format("%.3f", gameTimeVal)} ms") Text(text = "${String.format("%.3f", gameTimeVal)} ms")
Box(modifier = Modifier.width(84.dp)) {
MainActivity.performanceMonitor.RenderUsage()
}
}
} }
} }

View File

@ -252,7 +252,6 @@ class SettingViews {
.fillMaxWidth() .fillMaxWidth()
.padding(8.dp), .padding(8.dp),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) { ) {
Button(onClick = { Button(onClick = {
fun createIntent(action: String): Intent { fun createIntent(action: String): Intent {

View File

@ -1,6 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id 'com.android.application' version '8.1.0' apply false id 'com.android.application' version '8.2.1' apply false
id 'com.android.library' version '8.1.0' apply false id 'com.android.library' version '8.2.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
} }

View File

@ -1,6 +1,6 @@
#Fri Jun 30 08:45:05 UTC 2023 #Fri Jun 30 08:45:05 UTC 2023
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists