From 94efc95382ad2e5b4ebd9a80e757791e9b5f9ecf Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Thu, 14 Dec 2023 10:44:49 +0200 Subject: [PATCH 01/13] Android benchmark frame time. --- .../src/cpp/android_renderer_backend.cpp | 8 ++++++++ .../src/cpp/android_renderer_backend.hpp | 2 ++ .../MapboxGLAndroidSDK/src/cpp/native_map_view.cpp | 4 ++-- .../org/maplibre/android/maps/MapChangeReceiver.java | 4 ++-- .../main/java/org/maplibre/android/maps/MapView.java | 6 +++--- .../org/maplibre/android/maps/NativeMapView.java | 6 +++--- .../testapp/activity/benchmark/BenchmarkActivity.kt | 12 +++++++++++- .../testapp/activity/fragment/MapFragmentActivity.kt | 2 +- .../activity/fragment/SupportMapFragmentActivity.kt | 2 +- .../activity/imagegenerator/SnapshotActivity.kt | 2 +- .../testapp/activity/maplayout/MapChangeActivity.kt | 2 +- 11 files changed, 35 insertions(+), 15 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp index 2d8880a3e64..c091718b17d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp @@ -22,6 +22,10 @@ class AndroidGLRenderableResource final : public mbgl::gl::RenderableResource { backend.setViewport(0, 0, backend.getSize()); } + void swap() override { + backend.swap(); + } + private: AndroidRendererBackend& backend; }; @@ -51,6 +55,10 @@ PremultipliedImage AndroidRendererBackend::readFramebuffer() { return gl::RendererBackend::readFramebuffer(size); } +void AndroidRendererBackend::swap() { + static_cast(getContext()).finish(); +} + void AndroidRendererBackend::updateAssumedState() { assumeFramebufferBinding(0); assumeViewport(0, 0, size); diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.hpp b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.hpp index cdd9df9511c..ae65c26fd34 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.hpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.hpp @@ -19,6 +19,8 @@ class AndroidRendererBackend : public gl::RendererBackend, public mbgl::gfx::Ren void resizeFramebuffer(int width, int height); PremultipliedImage readFramebuffer(); + void swap(); + // mbgl::gfx::RendererBackend implementation public: mbgl::gfx::Renderable& getDefaultRenderable() override { return *this; } diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp b/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp index 59f0719149e..d04ee2d43cb 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp @@ -189,11 +189,11 @@ void NativeMapView::onDidFinishRenderingFrame(MapObserver::RenderFrameStatus sta android::UniqueEnv _env = android::AttachEnv(); static auto& javaClass = jni::Class::Singleton(*_env); - static auto onDidFinishRenderingFrame = javaClass.GetMethod(*_env, "onDidFinishRenderingFrame"); + static auto onDidFinishRenderingFrame = javaClass.GetMethod(*_env, "onDidFinishRenderingFrame"); auto weakReference = javaPeer.get(*_env); if (weakReference) { weakReference.Call( - *_env, onDidFinishRenderingFrame, (jboolean)(status.mode != MapObserver::RenderMode::Partial)); + *_env, onDidFinishRenderingFrame, (jboolean)(status.mode != MapObserver::RenderMode::Partial), (jdouble)status.frameEncodingTime, (jdouble)status.frameRenderingTime); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapChangeReceiver.java b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapChangeReceiver.java index 72d4d3e371d..7807c3d3286 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapChangeReceiver.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapChangeReceiver.java @@ -135,11 +135,11 @@ public void onWillStartRenderingFrame() { } @Override - public void onDidFinishRenderingFrame(boolean fully) { + public void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime) { try { if (!onDidFinishRenderingFrameList.isEmpty()) { for (MapView.OnDidFinishRenderingFrameListener listener : onDidFinishRenderingFrameList) { - listener.onDidFinishRenderingFrame(fully); + listener.onDidFinishRenderingFrame(fully, frameEncodingTime, frameRenderingTime); } } } catch (Throwable err) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapView.java index 8c927970c57..d603b3ab626 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapView.java @@ -1012,7 +1012,7 @@ public interface OnDidFinishRenderingFrameListener { * * @param fully true if all frames have been rendered, false if partially rendered */ - void onDidFinishRenderingFrame(boolean fully); + void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime); } /** @@ -1185,7 +1185,7 @@ private class InitialRenderCallback implements OnDidFinishRenderingFrameListener } @Override - public void onDidFinishRenderingFrame(boolean fully) { + public void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime) { if (maplibreMap != null && maplibreMap.getStyle() != null && maplibreMap.getStyle().isFullyLoaded()) { renderCount++; if (renderCount == 3) { @@ -1357,7 +1357,7 @@ public void onDidFailLoadingMap(String errorMessage) { } @Override - public void onDidFinishRenderingFrame(boolean fully) { + public void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime) { if (maplibreMap != null) { maplibreMap.onUpdateFullyRendered(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMapView.java index 5e1088c54b8..04ce5288f50 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMapView.java @@ -1091,9 +1091,9 @@ private void onWillStartRenderingFrame() { } @Keep - private void onDidFinishRenderingFrame(boolean fully) { + private void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime) { if (stateCallback != null) { - stateCallback.onDidFinishRenderingFrame(fully); + stateCallback.onDidFinishRenderingFrame(fully, frameEncodingTime, frameRenderingTime); } } @@ -1581,7 +1581,7 @@ interface StateCallback extends StyleCallback { void onWillStartRenderingFrame(); - void onDidFinishRenderingFrame(boolean fully); + void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime); void onWillStartRenderingMap(); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt index f903d03c2a6..439a05af9f4 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt @@ -33,6 +33,7 @@ import org.maplibre.android.testapp.BuildConfig import org.maplibre.android.testapp.R import org.maplibre.android.testapp.utils.FpsStore import org.maplibre.android.testapp.utils.BenchmarkResults +import timber.log.Timber import java.io.File import java.util.* @@ -179,10 +180,19 @@ class BenchmarkActivity : AppCompatActivity() { private fun setupMapView(savedInstanceState: Bundle?) { mapView = findViewById(R.id.mapView) as MapView + mapView.addOnDidFinishRenderingFrameListener( + MapView.OnDidFinishRenderingFrameListener { fully: Boolean, frameEncodingTime: Double, frameRenderingTime: Double -> + /*Timber.v( + "OnDidFinishRenderingFrame: fully: %s, encoding time: %.2f ms, rendering time: %.2f ms", + fully, frameEncodingTime * 1e3, frameRenderingTime * 1e3 + )*/ + fpsStore.add(frameEncodingTime * 1e3) + } + ) mapView.getMapAsync { maplibreMap: MapLibreMap -> this@BenchmarkActivity.maplibreMap = maplibreMap maplibreMap.setStyle(inputData.styleURLs[0]) - setFpsView(maplibreMap) + //setFpsView(maplibreMap) // Start an animation on the map as well flyTo(maplibreMap, 0, 0,14.0) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/MapFragmentActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/MapFragmentActivity.kt index 4a7f7f7a66b..d18b91dc3ad 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/MapFragmentActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/MapFragmentActivity.kt @@ -77,7 +77,7 @@ class MapFragmentActivity : } } - override fun onDidFinishRenderingFrame(fully: Boolean) { + override fun onDidFinishRenderingFrame(fully: Boolean, frameEncodingTime: Double, frameRenderingTime: Double) { if (initialCameraAnimation && fully && maplibreMap != null) { maplibreMap.animateCamera( CameraUpdateFactory.newCameraPosition(CameraPosition.Builder().tilt(45.0).build()), diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/SupportMapFragmentActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/SupportMapFragmentActivity.kt index 876617a7b0d..6c1a5f6d8d9 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/SupportMapFragmentActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/SupportMapFragmentActivity.kt @@ -75,7 +75,7 @@ class SupportMapFragmentActivity : mapView.removeOnDidFinishRenderingFrameListener(this) } - override fun onDidFinishRenderingFrame(fully: Boolean) { + override fun onDidFinishRenderingFrame(fully: Boolean, frameEncodingTime: Double, frameRenderingTime: Double) { if (initialCameraAnimation && fully && maplibreMap != null) { maplibreMap.animateCamera( CameraUpdateFactory.newCameraPosition(CameraPosition.Builder().tilt(45.0).build()), diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/imagegenerator/SnapshotActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/imagegenerator/SnapshotActivity.kt index cd062541bb5..7462750ce51 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/imagegenerator/SnapshotActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/imagegenerator/SnapshotActivity.kt @@ -20,7 +20,7 @@ class SnapshotActivity : AppCompatActivity(), OnMapReadyCallback { private lateinit var maplibreMap: MapLibreMap private val idleListener = object : MapView.OnDidFinishRenderingFrameListener { - override fun onDidFinishRenderingFrame(fully: Boolean) { + override fun onDidFinishRenderingFrame(fully: Boolean, frameEncodingTime: Double, frameRenderingTime: Double) { if (fully) { binding.mapView.removeOnDidFinishRenderingFrameListener(this) Logger.v(TAG, LOG_MESSAGE) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/maplayout/MapChangeActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/maplayout/MapChangeActivity.kt index 5f40e1bf81a..85413966838 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/maplayout/MapChangeActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/maplayout/MapChangeActivity.kt @@ -58,7 +58,7 @@ class MapChangeActivity : AppCompatActivity() { mapView.addOnDidFinishLoadingMapListener(OnDidFinishLoadingMapListener { Timber.v("OnDidFinishLoadingMap") }) mapView.addOnDidFinishLoadingStyleListener(OnDidFinishLoadingStyleListener { Timber.v("OnDidFinishLoadingStyle") }) mapView.addOnDidFinishRenderingFrameListener( - OnDidFinishRenderingFrameListener { fully: Boolean -> + OnDidFinishRenderingFrameListener { fully: Boolean, frameEncodingTime: Double, frameRenderingTime: Double -> Timber.v( "OnDidFinishRenderingFrame: fully: %s", fully From daecb3d8704a891fb77f3720389fbb9891e39a9f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 09:19:24 +0000 Subject: [PATCH 02/13] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../src/cpp/android_renderer_backend.cpp | 4 +--- .../MapboxGLAndroidSDK/src/cpp/native_map_view.cpp | 10 +++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp index c091718b17d..bb639c9b4e3 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp @@ -22,9 +22,7 @@ class AndroidGLRenderableResource final : public mbgl::gl::RenderableResource { backend.setViewport(0, 0, backend.getSize()); } - void swap() override { - backend.swap(); - } + void swap() override { backend.swap(); } private: AndroidRendererBackend& backend; diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp b/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp index d04ee2d43cb..988eb929a46 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/native_map_view.cpp @@ -189,11 +189,15 @@ void NativeMapView::onDidFinishRenderingFrame(MapObserver::RenderFrameStatus sta android::UniqueEnv _env = android::AttachEnv(); static auto& javaClass = jni::Class::Singleton(*_env); - static auto onDidFinishRenderingFrame = javaClass.GetMethod(*_env, "onDidFinishRenderingFrame"); + static auto onDidFinishRenderingFrame = javaClass.GetMethod( + *_env, "onDidFinishRenderingFrame"); auto weakReference = javaPeer.get(*_env); if (weakReference) { - weakReference.Call( - *_env, onDidFinishRenderingFrame, (jboolean)(status.mode != MapObserver::RenderMode::Partial), (jdouble)status.frameEncodingTime, (jdouble)status.frameRenderingTime); + weakReference.Call(*_env, + onDidFinishRenderingFrame, + (jboolean)(status.mode != MapObserver::RenderMode::Partial), + (jdouble)status.frameEncodingTime, + (jdouble)status.frameRenderingTime); } } From 0eb8bb617840073d8fe78d79bf57a3488d5a222b Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Thu, 14 Dec 2023 12:16:44 +0200 Subject: [PATCH 03/13] Added rendering time. --- .../activity/benchmark/BenchmarkActivity.kt | 28 +++++++++++++---- .../android/testapp/utils/BenchmarkUtils.kt | 31 +++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt index 439a05af9f4..9fa3c6b18d4 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt @@ -33,6 +33,7 @@ import org.maplibre.android.testapp.BuildConfig import org.maplibre.android.testapp.R import org.maplibre.android.testapp.utils.FpsStore import org.maplibre.android.testapp.utils.BenchmarkResults +import org.maplibre.android.testapp.utils.FrameTimeStore import timber.log.Timber import java.io.File @@ -82,7 +83,11 @@ class BenchmarkActivity : AppCompatActivity() { private var handler: Handler? = null private var delayed: Runnable? = null private var fpsStore = FpsStore() - private var results = BenchmarkResults() + private var encodingTimeStore = FrameTimeStore() + private var renderingTimeStore = FrameTimeStore() + private var fpsResults = BenchmarkResults() + private var encodingTimeResults = BenchmarkResults() + private var renderingTimeResults = BenchmarkResults() private var runsLeft = 5 // the styles used for the benchmark @@ -186,13 +191,14 @@ class BenchmarkActivity : AppCompatActivity() { "OnDidFinishRenderingFrame: fully: %s, encoding time: %.2f ms, rendering time: %.2f ms", fully, frameEncodingTime * 1e3, frameRenderingTime * 1e3 )*/ - fpsStore.add(frameEncodingTime * 1e3) + encodingTimeStore.add(frameEncodingTime * 1e3) + renderingTimeStore.add(frameRenderingTime * 1e3) } ) mapView.getMapAsync { maplibreMap: MapLibreMap -> this@BenchmarkActivity.maplibreMap = maplibreMap maplibreMap.setStyle(inputData.styleURLs[0]) - //setFpsView(maplibreMap) + setFpsView(maplibreMap) // Start an animation on the map as well flyTo(maplibreMap, 0, 0,14.0) @@ -216,10 +222,20 @@ class BenchmarkActivity : AppCompatActivity() { override fun onFinish() { if (place == PLACES.size - 1) { // done with tour - results.addResult(inputData.styleNames[style], fpsStore) + fpsResults.addResult(inputData.styleNames[style], fpsStore) fpsStore.reset() - println("FPS results $results") + println("FPS results $fpsResults") + + encodingTimeResults.addResult(inputData.styleNames[style], encodingTimeStore) + encodingTimeStore.reset() + + println("Encoding time results $encodingTimeResults") + + renderingTimeResults.addResult(inputData.styleNames[style], renderingTimeStore) + renderingTimeStore.reset() + + println("Rendering time results $renderingTimeResults") if (style < inputData.styleURLs.size - 1) { // continue with next style maplibreMap.setStyle(inputData.styleURLs[style + 1]) @@ -294,7 +310,7 @@ class BenchmarkActivity : AppCompatActivity() { val client = OkHttpClient() - val payload = jsonPayload(results) + val payload = jsonPayload(fpsResults) Logger.i(TAG, "Sending JSON payload to API: $payload") val request = Request.Builder() diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/utils/BenchmarkUtils.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/utils/BenchmarkUtils.kt index ef0b820c1d4..203457d6a8b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/utils/BenchmarkUtils.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/utils/BenchmarkUtils.kt @@ -23,6 +23,27 @@ class FpsStore { } } +class FrameTimeStore { + private val timeValues = ArrayList(100000) + + fun add(time: Double) { + timeValues.add(time) + } + + fun reset() { + timeValues.clear() + } + + fun low1p(): Double { + timeValues.sort() + return timeValues.slice((99 * timeValues.size / 100)..timeValues.size - 1).average() + } + + fun average(): Double { + return timeValues.average() + } +} + /** * Result of single benchmark run */ @@ -41,4 +62,14 @@ data class BenchmarkResults( ) resultsPerStyle[styleName] = newResults } + + fun addResult(styleName: String, frameTimeStore: FrameTimeStore) { + val newResults = resultsPerStyle.getValue(styleName).plus( + BenchmarkResult( + frameTimeStore.average(), + frameTimeStore.low1p() + ) + ) + resultsPerStyle[styleName] = newResults + } } \ No newline at end of file From 7cc0ef620653b66abf44f61eef0f0a5935f17dd8 Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Thu, 14 Dec 2023 13:40:36 +0200 Subject: [PATCH 04/13] Fix --- .../org/maplibre/android/maps/renderer/MapRenderer.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/renderer/MapRenderer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/renderer/MapRenderer.java index 0e8fe35b474..a0b0005a663 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/renderer/MapRenderer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/renderer/MapRenderer.java @@ -138,8 +138,10 @@ private native void nativeInitialize(MapRenderer self, private void updateFps() { long currentTime = System.nanoTime(); - double fps = 1E9 / ((currentTime - timeElapsed)); - onFpsChangedListener.onFpsChanged(fps); + if (timeElapsed > 0) { + double fps = 1E9 / ((currentTime - timeElapsed)); + onFpsChangedListener.onFpsChanged(fps); + } timeElapsed = currentTime; } From 9f762f3b8f15cee37c3f208bd3856aa70ae1d0b2 Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Thu, 14 Dec 2023 13:41:10 +0200 Subject: [PATCH 05/13] Removed fps reports. --- .../android/testapp/activity/benchmark/BenchmarkActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt index 9fa3c6b18d4..96e33a43deb 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt @@ -222,10 +222,10 @@ class BenchmarkActivity : AppCompatActivity() { override fun onFinish() { if (place == PLACES.size - 1) { // done with tour - fpsResults.addResult(inputData.styleNames[style], fpsStore) + /*fpsResults.addResult(inputData.styleNames[style], fpsStore) fpsStore.reset() - println("FPS results $fpsResults") + println("FPS results $fpsResults")*/ encodingTimeResults.addResult(inputData.styleNames[style], encodingTimeStore) encodingTimeStore.reset() From ebbbe987f7b09ca20cc666dd5d657ead6e58b0b3 Mon Sep 17 00:00:00 2001 From: Bart Louwers Date: Thu, 14 Dec 2023 20:38:47 +0100 Subject: [PATCH 06/13] Fix compilation --- .../maplibre/android/testapp/maps/RemoveUnusedImagesTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/maps/RemoveUnusedImagesTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/maps/RemoveUnusedImagesTest.kt index 3384f494c8c..40842838b61 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/maps/RemoveUnusedImagesTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/maps/RemoveUnusedImagesTest.kt @@ -60,7 +60,7 @@ class RemoveUnusedImagesTest : AppCenter() { mapView.addOnCanRemoveUnusedStyleImageListener { callbackLatch.countDown() maplibreMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 120.0), 8.0)) - mapView.addOnDidFinishRenderingFrameListener { + mapView.addOnDidFinishRenderingFrameListener{ _, _, _ -> assertNotNull(maplibreMap.style!!.getImage("small")) assertNotNull(maplibreMap.style!!.getImage("large")) latch.countDown() @@ -89,7 +89,7 @@ class RemoveUnusedImagesTest : AppCenter() { maplibreMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(0.0, 120.0), 8.0)) // Wait for the next frame and check that images were removed from the style. - mapView.addOnDidFinishRenderingFrameListener { + mapView.addOnDidFinishRenderingFrameListener { _, _, _ -> if (maplibreMap.style!!.getImage("small") == null && maplibreMap.style!!.getImage("large") == null) { latch.countDown() } From 666a0b85bd4b6d305e83468acd2fb6b644acea07 Mon Sep 17 00:00:00 2001 From: Bart Louwers Date: Thu, 14 Dec 2023 20:39:09 +0100 Subject: [PATCH 07/13] Include encoding and render time in jsonPayload --- .../activity/benchmark/BenchmarkActivity.kt | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt index 96e33a43deb..4bf0bec2b12 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt @@ -27,6 +27,7 @@ import org.maplibre.android.BuildConfig.GIT_REVISION import org.maplibre.android.camera.CameraUpdateFactory import org.maplibre.android.geometry.LatLng import org.maplibre.android.log.Logger +import org.maplibre.android.log.Logger.INFO import org.maplibre.android.maps.* import org.maplibre.android.maps.MapLibreMap.CancelableCallback import org.maplibre.android.testapp.BuildConfig @@ -54,13 +55,32 @@ data class BenchmarkInputData( * Prepares JSON payload that is sent to the API that collects benchmark results. * See https://github.com/maplibre/ci-runners */ -fun jsonPayload(results: BenchmarkResults): JsonObject { +@SuppressLint("NewApi") +fun jsonPayload(styleNames: List, fpsResults: BenchmarkResults, encodingTimeResults: BenchmarkResults, renderingTimeResults: BenchmarkResults): JsonObject { return buildJsonObject { putJsonObject("resultsPerStyle") { - for ((styleName, result) in results.resultsPerStyle) { - putJsonObject(styleName) { - put("avgFps", JsonPrimitive(result.map { it.average }.average())) - put("low1p", JsonPrimitive(result.map { it.low1p }.average())) + for (style in styleNames) { + putJsonObject(style) { + fpsResults.resultsPerStyle[style].let { results -> + if (results !== null) { + put("avgFps", JsonPrimitive(results.map { it.average }.average())) + put("low1pFps", JsonPrimitive(results.map { it.low1p }.average())) + } + } + + encodingTimeResults.resultsPerStyle[style].let { results -> + if (results !== null) { + put("avgEncodingTime", JsonPrimitive(results.map { it.average }.average())) + put("low1pEncodingTime", JsonPrimitive(results.map { it.low1p }.average())) + } + } + + renderingTimeResults.resultsPerStyle[style].let { results -> + if (results !== null) { + put("avgRenderingTime", JsonPrimitive(results.map { it.average }.average())) + put("low1pRenderingTime", JsonPrimitive(results.map { it.low1p }.average())) + } + } } } } @@ -166,6 +186,8 @@ class BenchmarkActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + Logger.setVerbosity(INFO) + setContentView(R.layout.activity_benchmark) window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -231,6 +253,7 @@ class BenchmarkActivity : AppCompatActivity() { encodingTimeStore.reset() println("Encoding time results $encodingTimeResults") + println("Benchmark ${jsonPayload(inputData.styleNames, fpsResults, encodingTimeResults, renderingTimeResults)}") renderingTimeResults.addResult(inputData.styleNames[style], renderingTimeStore) renderingTimeStore.reset() @@ -310,7 +333,7 @@ class BenchmarkActivity : AppCompatActivity() { val client = OkHttpClient() - val payload = jsonPayload(fpsResults) + val payload = jsonPayload(inputData.styleNames, fpsResults, encodingTimeResults, renderingTimeResults) Logger.i(TAG, "Sending JSON payload to API: $payload") val request = Request.Builder() From 64e38fffc9de1eabf106801a83902fdf86824361 Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Tue, 16 Jan 2024 19:20:38 +0200 Subject: [PATCH 08/13] Compute only frames time that have the map fully loaded. --- .../main/java/org/maplibre/android/maps/MapLibreMap.java | 4 ++++ .../android/testapp/activity/benchmark/BenchmarkActivity.kt | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapLibreMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapLibreMap.java index db5873653c8..44f50cfdac9 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapLibreMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapLibreMap.java @@ -113,6 +113,10 @@ void initialise(@NonNull Context context, @NonNull MapLibreMapOptions options) { setPrefetchesTiles(options); } + public boolean isFullyLoaded() { + return nativeMapView.isFullyLoaded(); + } + /** * Get the Style of the map asynchronously. */ diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt index 4bf0bec2b12..cd578066fae 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt @@ -213,8 +213,10 @@ class BenchmarkActivity : AppCompatActivity() { "OnDidFinishRenderingFrame: fully: %s, encoding time: %.2f ms, rendering time: %.2f ms", fully, frameEncodingTime * 1e3, frameRenderingTime * 1e3 )*/ - encodingTimeStore.add(frameEncodingTime * 1e3) - renderingTimeStore.add(frameRenderingTime * 1e3) + if (maplibreMap.isFullyLoaded()) { + encodingTimeStore.add(frameEncodingTime * 1e3) + renderingTimeStore.add(frameRenderingTime * 1e3) + } } ) mapView.getMapAsync { maplibreMap: MapLibreMap -> From deb5517db8ccacf7909ef3b822974ee1af730e86 Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Thu, 1 Feb 2024 08:48:52 +0200 Subject: [PATCH 09/13] Fix Android test. --- .../android/maps/MapChangeReceiverTest.kt | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/org/maplibre/android/maps/MapChangeReceiverTest.kt b/platform/android/MapboxGLAndroidSDK/src/test/java/org/maplibre/android/maps/MapChangeReceiverTest.kt index 9a41d4cc513..37d1d285af7 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/org/maplibre/android/maps/MapChangeReceiverTest.kt +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/org/maplibre/android/maps/MapChangeReceiverTest.kt @@ -401,22 +401,22 @@ class MapChangeReceiverTest { mapChangeEventManager!!.addOnDidFinishRenderingFrameListener( onDidFinishRenderingFrameListener ) - mapChangeEventManager!!?.onDidFinishRenderingFrame(true) - Mockito.verify(onDidFinishRenderingFrameListener)?.onDidFinishRenderingFrame(true) + mapChangeEventManager!!?.onDidFinishRenderingFrame(true, .0, .0) + Mockito.verify(onDidFinishRenderingFrameListener)?.onDidFinishRenderingFrame(true, .0, .0) mapChangeEventManager!!.removeOnDidFinishRenderingFrameListener( onDidFinishRenderingFrameListener ) - mapChangeEventManager!!?.onDidFinishRenderingFrame(true) - Mockito.verify(onDidFinishRenderingFrameListener)?.onDidFinishRenderingFrame(true) + mapChangeEventManager!!?.onDidFinishRenderingFrame(true, .0, .0) + Mockito.verify(onDidFinishRenderingFrameListener)?.onDidFinishRenderingFrame(true,.0, .0) mapChangeEventManager!!.addOnDidFinishRenderingFrameListener( onDidFinishRenderingFrameListener ) Logger.setLoggerDefinition(loggerDefinition) val exc: Exception = RuntimeException() Mockito.doThrow(exc).`when`(onDidFinishRenderingFrameListener) - ?.onDidFinishRenderingFrame(true) + ?.onDidFinishRenderingFrame(true, .0, .0) try { - mapChangeEventManager!!?.onDidFinishRenderingFrame(true) + mapChangeEventManager!!?.onDidFinishRenderingFrame(true, .0, .0) Assert.fail("The exception should've been re-thrown.") } catch (throwable: RuntimeException) { Mockito.verify(loggerDefinition)?.e( @@ -427,9 +427,9 @@ class MapChangeReceiverTest { } val err: Error = ExecutionError("", Error()) Mockito.doThrow(err).`when`(onDidFinishRenderingFrameListener) - ?.onDidFinishRenderingFrame(true) + ?.onDidFinishRenderingFrame(true, .0, .0) try { - mapChangeEventManager!!?.onDidFinishRenderingFrame(true) + mapChangeEventManager!!?.onDidFinishRenderingFrame(true, .0, .0) Assert.fail("The exception should've been re-thrown.") } catch (throwable: ExecutionError) { Mockito.verify(loggerDefinition)?.e( @@ -445,22 +445,22 @@ class MapChangeReceiverTest { mapChangeEventManager!!.addOnDidFinishRenderingFrameListener( onDidFinishRenderingFrameListener ) - mapChangeEventManager!!?.onDidFinishRenderingFrame(false) - Mockito.verify(onDidFinishRenderingFrameListener)?.onDidFinishRenderingFrame(false) + mapChangeEventManager!!?.onDidFinishRenderingFrame(false, .0, .0) + Mockito.verify(onDidFinishRenderingFrameListener)?.onDidFinishRenderingFrame(false, .0, .0) mapChangeEventManager!!.removeOnDidFinishRenderingFrameListener( onDidFinishRenderingFrameListener ) - mapChangeEventManager!!?.onDidFinishRenderingFrame(false) - Mockito.verify(onDidFinishRenderingFrameListener)?.onDidFinishRenderingFrame(false) + mapChangeEventManager!!?.onDidFinishRenderingFrame(false, .0, .0) + Mockito.verify(onDidFinishRenderingFrameListener)?.onDidFinishRenderingFrame(false, .0, .0) mapChangeEventManager!!.addOnDidFinishRenderingFrameListener( onDidFinishRenderingFrameListener ) Logger.setLoggerDefinition(loggerDefinition) val exc: Exception = RuntimeException() Mockito.doThrow(exc).`when`(onDidFinishRenderingFrameListener) - ?.onDidFinishRenderingFrame(false) + ?.onDidFinishRenderingFrame(false, .0, .0) try { - mapChangeEventManager!!?.onDidFinishRenderingFrame(false) + mapChangeEventManager!!?.onDidFinishRenderingFrame(false, .0, .0) Assert.fail("The exception should've been re-thrown.") } catch (throwable: RuntimeException) { Mockito.verify(loggerDefinition)?.e( @@ -471,9 +471,9 @@ class MapChangeReceiverTest { } val err: Error = ExecutionError("", Error()) Mockito.doThrow(err).`when`(onDidFinishRenderingFrameListener) - ?.onDidFinishRenderingFrame(false) + ?.onDidFinishRenderingFrame(false, .0, .0) try { - mapChangeEventManager!!?.onDidFinishRenderingFrame(false) + mapChangeEventManager!!?.onDidFinishRenderingFrame(false, .0, .0) Assert.fail("The exception should've been re-thrown.") } catch (throwable: ExecutionError) { Mockito.verify(loggerDefinition)?.e( From 24e6145aea680ba7bba5e65246b550d4d9c71aa0 Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Thu, 1 Feb 2024 19:58:56 +0200 Subject: [PATCH 10/13] Exposed setSwapBehavior. --- include/mbgl/gfx/renderable.hpp | 6 ++++++ .../src/cpp/android_renderer_backend.cpp | 14 ++++++++++---- .../src/cpp/android_renderer_backend.hpp | 4 ++++ .../MapboxGLAndroidSDK/src/cpp/map_renderer.cpp | 7 ++++++- .../MapboxGLAndroidSDK/src/cpp/map_renderer.hpp | 2 ++ .../org/maplibre/android/maps/MapLibreMap.java | 4 ++++ .../java/org/maplibre/android/maps/NativeMap.java | 2 ++ .../org/maplibre/android/maps/NativeMapView.java | 5 +++++ .../android/maps/renderer/MapRenderer.java | 6 ++++++ .../activity/benchmark/BenchmarkActivity.kt | 1 + .../default/include/mbgl/gfx/headless_backend.hpp | 5 ----- platform/default/src/mbgl/gl/headless_backend.cpp | 2 +- 12 files changed, 47 insertions(+), 11 deletions(-) diff --git a/include/mbgl/gfx/renderable.hpp b/include/mbgl/gfx/renderable.hpp index dd95dc12315..f6c707d6eee 100644 --- a/include/mbgl/gfx/renderable.hpp +++ b/include/mbgl/gfx/renderable.hpp @@ -21,6 +21,12 @@ class RenderableResource { }; class Renderable { +public: + enum class SwapBehaviour { + NoFlush, + Flush + }; + protected: Renderable(const Size size_, std::unique_ptr resource_) : size(size_), diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp index bb639c9b4e3..993dfacd146 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp @@ -53,10 +53,6 @@ PremultipliedImage AndroidRendererBackend::readFramebuffer() { return gl::RendererBackend::readFramebuffer(size); } -void AndroidRendererBackend::swap() { - static_cast(getContext()).finish(); -} - void AndroidRendererBackend::updateAssumedState() { assumeFramebufferBinding(0); assumeViewport(0, 0, size); @@ -68,5 +64,15 @@ void AndroidRendererBackend::markContextLost() { } } +void AndroidRendererBackend::setSwapBehavior(SwapBehaviour swapBehaviour_) { + swapBehaviour = swapBehaviour_; +} + +void AndroidRendererBackend::swap() { + if( swapBehaviour == SwapBehaviour::Flush) { + static_cast(getContext()).finish(); + } +} + } // namespace android } // namespace mbgl diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.hpp b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.hpp index ae65c26fd34..9b06a6cca14 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.hpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.hpp @@ -19,8 +19,12 @@ class AndroidRendererBackend : public gl::RendererBackend, public mbgl::gfx::Ren void resizeFramebuffer(int width, int height); PremultipliedImage readFramebuffer(); + void setSwapBehavior(SwapBehaviour swapBehaviour); void swap(); +private: + SwapBehaviour swapBehaviour = SwapBehaviour::NoFlush; + // mbgl::gfx::RendererBackend implementation public: mbgl::gfx::Renderable& getDefaultRenderable() override { return *this; } diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/map_renderer.cpp b/platform/android/MapboxGLAndroidSDK/src/cpp/map_renderer.cpp index 4941e3316f9..3ea039d1fda 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/map_renderer.cpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/map_renderer.cpp @@ -236,6 +236,10 @@ void MapRenderer::onSurfaceDestroyed(JNIEnv&) { resetRenderer(); } +void MapRenderer::setSwapBehaviorFlush(JNIEnv&, jboolean flush) { + backend->setSwapBehavior(flush ? gfx::Renderable::SwapBehaviour::Flush : gfx::Renderable::SwapBehaviour::NoFlush); +} + // Static methods // void MapRenderer::registerNative(jni::JNIEnv& env) { @@ -256,7 +260,8 @@ void MapRenderer::registerNative(jni::JNIEnv& env) { METHOD(&MapRenderer::onRendererReset, "nativeReset"), METHOD(&MapRenderer::onSurfaceCreated, "nativeOnSurfaceCreated"), METHOD(&MapRenderer::onSurfaceChanged, "nativeOnSurfaceChanged"), - METHOD(&MapRenderer::onSurfaceDestroyed, "nativeOnSurfaceDestroyed")); + METHOD(&MapRenderer::onSurfaceDestroyed, "nativeOnSurfaceDestroyed"), + METHOD(&MapRenderer::setSwapBehaviorFlush, "nativeSetSwapBehaviorFlush")); } MapRenderer& MapRenderer::getNativePeer(JNIEnv& env, const jni::Object& jObject) { diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/map_renderer.hpp b/platform/android/MapboxGLAndroidSDK/src/cpp/map_renderer.hpp index 41f0259a50d..25ffc60695d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/map_renderer.hpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/map_renderer.hpp @@ -107,6 +107,8 @@ class MapRenderer : public Scheduler { // Called on either Main or GL thread // void onRendererReset(JNIEnv&); + void setSwapBehaviorFlush(JNIEnv&, jboolean flush); + private: jni::WeakReference, jni::EnvAttachingDeleter> javaPeer; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapLibreMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapLibreMap.java index db5873653c8..47748d9bd3b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapLibreMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/MapLibreMap.java @@ -103,6 +103,10 @@ public void triggerRepaint() { nativeMapView.triggerRepaint(); } + public void setSwapBehaviorFlush(boolean flush) { + nativeMapView.setSwapBehaviorFlush(flush); + } + void initialise(@NonNull Context context, @NonNull MapLibreMapOptions options) { transform.initialise(this, options); uiSettings.initialise(context, options); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMap.java index 36da6e4184d..48993886b43 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMap.java @@ -239,6 +239,8 @@ List queryRenderedFeatures(@NonNull RectF coordinates, void triggerRepaint(); + void setSwapBehaviorFlush(boolean flush); + // // Deprecated Annotations API // diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMapView.java index 04ce5288f50..9caea12b70c 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/NativeMapView.java @@ -1026,6 +1026,11 @@ public void triggerRepaint() { nativeTriggerRepaint(); } + @Override + public void setSwapBehaviorFlush(boolean flush) { + mapRenderer.setSwapBehaviorFlush(flush); + } + @NonNull @Override public RectF getDensityDependantRectangle(final RectF rectangle) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/renderer/MapRenderer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/renderer/MapRenderer.java index a0b0005a663..7be40232479 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/renderer/MapRenderer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/maps/renderer/MapRenderer.java @@ -102,6 +102,10 @@ protected void onDrawFrame(GL10 gl) { } } + public void setSwapBehaviorFlush(boolean flush) { + nativeSetSwapBehaviorFlush(flush); + } + /** * May be called from any thread. *

@@ -134,6 +138,8 @@ private native void nativeInitialize(MapRenderer self, private native void nativeRender(); + private native void nativeSetSwapBehaviorFlush(boolean flush); + private long timeElapsed; private void updateFps() { diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt index 4bf0bec2b12..42bb2993f49 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt @@ -220,6 +220,7 @@ class BenchmarkActivity : AppCompatActivity() { mapView.getMapAsync { maplibreMap: MapLibreMap -> this@BenchmarkActivity.maplibreMap = maplibreMap maplibreMap.setStyle(inputData.styleURLs[0]) + maplibreMap.setSwapBehaviorFlush(true) setFpsView(maplibreMap) // Start an animation on the map as well diff --git a/platform/default/include/mbgl/gfx/headless_backend.hpp b/platform/default/include/mbgl/gfx/headless_backend.hpp index 1dc7755317d..e6a3c9e539c 100644 --- a/platform/default/include/mbgl/gfx/headless_backend.hpp +++ b/platform/default/include/mbgl/gfx/headless_backend.hpp @@ -15,11 +15,6 @@ namespace gfx { // of readStillImage. class HeadlessBackend : public gfx::Renderable { public: - enum class SwapBehaviour { - NoFlush, - Flush - }; - // Factory. static std::unique_ptr Create(const Size size = {256, 256}, SwapBehaviour swapBehavior = SwapBehaviour::NoFlush, diff --git a/platform/default/src/mbgl/gl/headless_backend.cpp b/platform/default/src/mbgl/gl/headless_backend.cpp index 816c38e7078..ccfe6936d0a 100644 --- a/platform/default/src/mbgl/gl/headless_backend.cpp +++ b/platform/default/src/mbgl/gl/headless_backend.cpp @@ -111,7 +111,7 @@ namespace gfx { template <> std::unique_ptr Backend::Create( - const Size size, gfx::HeadlessBackend::SwapBehaviour swapBehavior, const gfx::ContextMode contextMode) { + const Size size, gfx::Renderable::SwapBehaviour swapBehavior, const gfx::ContextMode contextMode) { return std::make_unique(size, swapBehavior, contextMode); } From 724fc3f0439317dc87c8f0d2c1d48fb58a8697fa Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 17:59:32 +0000 Subject: [PATCH 11/13] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp index 993dfacd146..c20b21ced18 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_backend.cpp @@ -69,8 +69,8 @@ void AndroidRendererBackend::setSwapBehavior(SwapBehaviour swapBehaviour_) { } void AndroidRendererBackend::swap() { - if( swapBehaviour == SwapBehaviour::Flush) { - static_cast(getContext()).finish(); + if (swapBehaviour == SwapBehaviour::Flush) { + static_cast(getContext()).finish(); } } From 43b04fa7c1c6b41fe6ddef1080ffdb6fee3a84ee Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Thu, 1 Feb 2024 20:38:14 +0200 Subject: [PATCH 12/13] Added measureFrameTime variable to enable time measure instead of fps. --- .../activity/benchmark/BenchmarkActivity.kt | 63 +++++++++---------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt index 42bb2993f49..b67532a1027 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt @@ -8,7 +8,6 @@ import android.os.Environment import android.os.Handler import android.view.View import android.view.WindowManager -import androidx.annotation.RequiresApi import androidx.appcompat.app.AppCompatActivity import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -35,7 +34,6 @@ import org.maplibre.android.testapp.R import org.maplibre.android.testapp.utils.FpsStore import org.maplibre.android.testapp.utils.BenchmarkResults import org.maplibre.android.testapp.utils.FrameTimeStore -import timber.log.Timber import java.io.File import java.util.* @@ -99,7 +97,6 @@ class BenchmarkActivity : AppCompatActivity() { private val TAG = "BenchmarkActivity" private lateinit var mapView: MapView - private lateinit var maplibreMap: MapLibreMap private var handler: Handler? = null private var delayed: Runnable? = null private var fpsStore = FpsStore() @@ -109,6 +106,7 @@ class BenchmarkActivity : AppCompatActivity() { private var encodingTimeResults = BenchmarkResults() private var renderingTimeResults = BenchmarkResults() private var runsLeft = 5 + private var measureFrameTime = true // the styles used for the benchmark // can be overridden adding with developer-config.xml @@ -207,21 +205,20 @@ class BenchmarkActivity : AppCompatActivity() { private fun setupMapView(savedInstanceState: Bundle?) { mapView = findViewById(R.id.mapView) as MapView - mapView.addOnDidFinishRenderingFrameListener( - MapView.OnDidFinishRenderingFrameListener { fully: Boolean, frameEncodingTime: Double, frameRenderingTime: Double -> - /*Timber.v( - "OnDidFinishRenderingFrame: fully: %s, encoding time: %.2f ms, rendering time: %.2f ms", - fully, frameEncodingTime * 1e3, frameRenderingTime * 1e3 - )*/ + if (measureFrameTime) { + mapView.addOnDidFinishRenderingFrameListener { fully: Boolean, frameEncodingTime: Double, frameRenderingTime: Double -> encodingTimeStore.add(frameEncodingTime * 1e3) renderingTimeStore.add(frameRenderingTime * 1e3) } - ) + } mapView.getMapAsync { maplibreMap: MapLibreMap -> - this@BenchmarkActivity.maplibreMap = maplibreMap maplibreMap.setStyle(inputData.styleURLs[0]) - maplibreMap.setSwapBehaviorFlush(true) - setFpsView(maplibreMap) + maplibreMap.setSwapBehaviorFlush(measureFrameTime) + if (!measureFrameTime) { + maplibreMap.setOnFpsChangedListener { fps: Double -> + fpsStore.add(fps) + } + } // Start an animation on the map as well flyTo(maplibreMap, 0, 0,14.0) @@ -245,22 +242,30 @@ class BenchmarkActivity : AppCompatActivity() { override fun onFinish() { if (place == PLACES.size - 1) { // done with tour - /*fpsResults.addResult(inputData.styleNames[style], fpsStore) - fpsStore.reset() - - println("FPS results $fpsResults")*/ - - encodingTimeResults.addResult(inputData.styleNames[style], encodingTimeStore) - encodingTimeStore.reset() + if (measureFrameTime) { + encodingTimeResults.addResult( + inputData.styleNames[style], + encodingTimeStore + ) + encodingTimeStore.reset() + + println("Encoding time results $encodingTimeResults") + + renderingTimeResults.addResult( + inputData.styleNames[style], + renderingTimeStore + ) + renderingTimeStore.reset() + + println("Rendering time results $renderingTimeResults") + } else { + fpsResults.addResult(inputData.styleNames[style], fpsStore) + fpsStore.reset() - println("Encoding time results $encodingTimeResults") + println("FPS results $fpsResults") + } println("Benchmark ${jsonPayload(inputData.styleNames, fpsResults, encodingTimeResults, renderingTimeResults)}") - renderingTimeResults.addResult(inputData.styleNames[style], renderingTimeStore) - renderingTimeStore.reset() - - println("Rendering time results $renderingTimeResults") - if (style < inputData.styleURLs.size - 1) { // continue with next style maplibreMap.setStyle(inputData.styleURLs[style + 1]) flyTo(maplibreMap, 0, style + 1, zoom) @@ -281,12 +286,6 @@ class BenchmarkActivity : AppCompatActivity() { ) } - private fun setFpsView(maplibreMap: MapLibreMap) { - maplibreMap.setOnFpsChangedListener { fps: Double -> - fpsStore.add(fps) - } - } - override fun onStart() { super.onStart() mapView.onStart() From b73cfc7695642d719e77b72e0c8f41d090ef89b5 Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Fri, 2 Feb 2024 16:18:01 +0200 Subject: [PATCH 13/13] Fix after merge. --- .../android/testapp/activity/benchmark/BenchmarkActivity.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt index 974b2a7b152..3f9f5f9ade6 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/org/maplibre/android/testapp/activity/benchmark/BenchmarkActivity.kt @@ -97,6 +97,7 @@ class BenchmarkActivity : AppCompatActivity() { private val TAG = "BenchmarkActivity" private lateinit var mapView: MapView + private lateinit var maplibreMap: MapLibreMap private var handler: Handler? = null private var delayed: Runnable? = null private var fpsStore = FpsStore() @@ -214,6 +215,7 @@ class BenchmarkActivity : AppCompatActivity() { } } mapView.getMapAsync { maplibreMap: MapLibreMap -> + this.maplibreMap = maplibreMap maplibreMap.setStyle(inputData.styleURLs[0]) maplibreMap.setSwapBehaviorFlush(measureFrameTime) if (!measureFrameTime) {