Benchmark activity Android (#1850)

This commit is contained in:
Bart Louwers
2023-12-01 15:34:57 +01:00
committed by GitHub
parent 0b4c95593c
commit 454efb64ac
4 changed files with 243 additions and 0 deletions

View File

@@ -1181,6 +1181,20 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity" />
</activity>
<!-- Benchmark -->
<activity
android:name=".activity.benchmark.BenchmarkActivity"
android:description="@string/description_world_tour_benchmark"
android:exported="true"
android:label="@string/activity_benchmark_world_tour"
>
<meta-data
android:name="@string/category"
android:value="@string/category_benchmark" />
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity" />
</activity>
<!-- For Instrumentation tests -->
<activity
android:name=".activity.style.RuntimeStyleTimingTestActivity"

View File

@@ -0,0 +1,211 @@
package org.maplibre.android.testapp.activity.benchmark
import android.annotation.SuppressLint
import android.os.Bundle
import android.os.Handler
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import org.maplibre.android.camera.CameraUpdateFactory
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.*
import org.maplibre.android.maps.MapLibreMap.CancelableCallback
import org.maplibre.android.testapp.R
import java.util.*
class FpsStore {
private val fpsValues = ArrayList<Double>(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<String, List<Result>> = mutableMapOf<String, List<Result>>().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
// <array name="benchmark_style_names">
// <item>Americana</item>
// </array>
// <array name="benchmark_style_urls">
// <item>https://zelonewolf.github.io/openstreetmap-americana/style.json</item>
// </array>
// ```
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<View>(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
)
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.benchmark.BenchmarkActivity">
<org.maplibre.android.maps.MapView
android:id="@id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:maplibre_renderTextureMode="true"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -4,4 +4,7 @@
<string name="fps30">fps30</string>
<string name="fps60">fps60</string>
<string name="this_is_an_empty_fragment">This is an empty Fragment</string>
<string name="category_benchmark">Benchmark</string>
<string name="activity_benchmark_world_tour">World Tour Benchmark</string>
<string name="description_world_tour_benchmark">Writes out avg. fps and 1% fps after world tour with .flyTo()</string>
</resources>