From 454efb64ac0aa549883d8401858687ef419b8d54 Mon Sep 17 00:00:00 2001 From: Bart Louwers Date: Fri, 1 Dec 2023 15:34:57 +0100 Subject: [PATCH] Benchmark activity Android (#1850) --- .../src/main/AndroidManifest.xml | 14 ++ .../activity/benchmark/BenchmarkActivity.kt | 211 ++++++++++++++++++ .../main/res/layout/activity_benchmark.xml | 15 ++ .../src/main/res/values/strings.xml | 3 + 4 files changed, 243 insertions(+) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_benchmark.xml diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml index d94d21718..494b37eee 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml @@ -1181,6 +1181,20 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".activity.FeatureOverviewActivity" /> + + + + + (100000) + + fun add(fps: Double) { + fpsValues.add(fps) + } + + fun reset() { + fpsValues.clear() + } + + fun low1p(): Double { + fpsValues.sort() + return fpsValues.slice(0..(fpsValues.size / 100)).average() + } + + fun average(): Double { + return fpsValues.average() + } +} + +data class Result(val average: Double, val low1p: Double) + +data class Results( + var map: MutableMap> = mutableMapOf>().withDefault { emptyList() }) + { + + fun addResult(styleName: String, fpsStore: FpsStore) { + val newResults = map.getValue(styleName).plus(Result(fpsStore.average(), fpsStore.low1p())) + map[styleName] = newResults + } +} + +/** + * Benchmark using a [android.view.TextureView] + */ +class BenchmarkActivity : AppCompatActivity() { + private lateinit var mapView: MapView + private lateinit var maplibreMap: MapLibreMap + private var handler: Handler? = null + private var delayed: Runnable? = null + private var fpsStore = FpsStore() + private var results = Results() + private var runsLeft = 5 + + // the styles used for the benchmark + // can be overridden adding with developer-config.xml + // ```xml + // + // Americana + // + // + // https://zelonewolf.github.io/openstreetmap-americana/style.json + // + // ``` + private var styles = listOf(Pair("Demotiles", "https://demotiles.maplibre.org/style.json")) + + @SuppressLint("DiscouragedApi") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_benchmark) + handler = Handler(mainLooper) + setupToolbar() + setupMapView(savedInstanceState) + + val styleNames = resources.getStringArray(applicationContext.resources.getIdentifier( + "benchmark_style_names", + "array", + applicationContext.packageName)) + val styleURLs = resources.getStringArray(applicationContext.resources.getIdentifier( + "benchmark_style_urls", + "array", + applicationContext.packageName)) + if (styleNames.isNotEmpty() && styleNames.size == styleURLs.size) { + styles = styleNames.zip(styleURLs) + } + } + + private fun setupToolbar() { + val actionBar = supportActionBar + if (actionBar != null) { + supportActionBar!!.setDisplayHomeAsUpEnabled(true) + supportActionBar!!.setHomeButtonEnabled(true) + } + } + + private fun setupMapView(savedInstanceState: Bundle?) { + mapView = findViewById(R.id.mapView) as MapView + mapView.getMapAsync { maplibreMap: MapLibreMap -> + this@BenchmarkActivity.maplibreMap = maplibreMap + maplibreMap.setStyle(styles[0].second) + setFpsView(maplibreMap) + + // Start an animation on the map as well + flyTo(maplibreMap, 0, 0,14.0) + } + } + + private fun flyTo(maplibreMap: MapLibreMap, place: Int, style: Int, zoom: Double) { + maplibreMap.animateCamera( + CameraUpdateFactory.newLatLngZoom(PLACES[place], zoom), + 10000, + object : CancelableCallback { + override fun onCancel() { + delayed = Runnable { + delayed = null + flyTo(maplibreMap, place, style, zoom) + } + delayed?.let { + handler!!.postDelayed(it, 2000) + } + } + + override fun onFinish() { + if (place == PLACES.size - 1) { // done with tour + results.addResult(styles[style].first, fpsStore) + fpsStore.reset() + + println("FPS results $results") + + if (style < styles.size - 1) { // continue with next style + maplibreMap.setStyle(styles[style + 1].second) + flyTo(maplibreMap, 0, style + 1, zoom) + } else if (runsLeft > 0) { // start over + --runsLeft + maplibreMap.setStyle(styles[0].second) + flyTo(maplibreMap, 0, 0, zoom) + } else { + finish() + } + return + } + + // continue with next place + flyTo(maplibreMap, place + 1, style, zoom) + } + } + ) + } + + private fun setFpsView(maplibreMap: MapLibreMap) { + maplibreMap.setOnFpsChangedListener { fps: Double -> + fpsStore.add(fps) + } + } + + override fun onStart() { + super.onStart() + mapView.onStart() + } + + override fun onResume() { + super.onResume() + mapView.onResume() + } + + override fun onPause() { + super.onPause() + mapView.onPause() + } + + override fun onStop() { + super.onStop() + mapView.onStop() + if (handler != null && delayed != null) { + handler!!.removeCallbacks(delayed!!) + } + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + mapView.onSaveInstanceState(outState) + } + + override fun onDestroy() { + super.onDestroy() + mapView.onDestroy() + } + + override fun onLowMemory() { + super.onLowMemory() + mapView.onLowMemory() + } + + companion object { + private val PLACES = arrayOf( + LatLng(37.7749, -122.4194), // SF + LatLng(38.9072, -77.0369), // DC + LatLng(52.3702, 4.8952), // AMS + LatLng(60.1699, 24.9384), // HEL + LatLng(-13.1639, -74.2236), // AYA + LatLng(52.5200, 13.4050), // BER + LatLng(12.9716, 77.5946), // BAN + LatLng(31.2304, 121.4737) // SHA + ) + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_benchmark.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_benchmark.xml new file mode 100644 index 000000000..4a9c8d9d0 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_benchmark.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml index 6b21dc424..1b8d9d849 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml @@ -4,4 +4,7 @@ fps30 fps60 This is an empty Fragment + Benchmark + World Tour Benchmark + Writes out avg. fps and 1% fps after world tour with .flyTo()