From dd489469879a38f404051bc97ff2b8ba075f91be Mon Sep 17 00:00:00 2001 From: Adrian Cojocaru Date: Wed, 11 Feb 2026 13:35:08 +0200 Subject: [PATCH] fix Android Vulkan instrumentation tests (#4091) --- include/mbgl/vulkan/renderer_backend.hpp | 4 +-- .../MapLibreAndroid/src/cpp/map_renderer.cpp | 6 +---- .../textureview/TextureViewRenderThread.java | 2 +- .../VulkanTextureViewRenderThread.java | 25 ++++++++----------- .../android/testapp/MapLibreApplication.kt | 1 + .../activity/fragment/ViewPagerActivity.kt | 2 +- ...ibre.download-vulkan-validation.gradle.kts | 2 +- 7 files changed, 18 insertions(+), 24 deletions(-) diff --git a/include/mbgl/vulkan/renderer_backend.hpp b/include/mbgl/vulkan/renderer_backend.hpp index 8f2f21107..67ef4d1ed 100644 --- a/include/mbgl/vulkan/renderer_backend.hpp +++ b/include/mbgl/vulkan/renderer_backend.hpp @@ -19,7 +19,7 @@ #define VMA_DYNAMIC_VULKAN_FUNCTIONS 0 #include "vk_mem_alloc.h" -#ifndef NDEBUG +#if !defined(NDEBUG) && !defined(__ANDROID__) #define ENABLE_VULKAN_VALIDATION // #define ENABLE_VULKAN_GPU_ASSISTED_VALIDATION // #define ENABLE_VMA_DEBUG @@ -61,7 +61,7 @@ public: if (!debugUtilsEnabled) return; const uint64_t handle = reinterpret_cast(static_cast(object)); device->setDebugUtilsObjectNameEXT(vk::DebugUtilsObjectNameInfoEXT() - .setObjectType(object.objectType) + .setObjectType(T::objectType) .setObjectHandle(handle) .setPObjectName(name.c_str()), dispatcher); diff --git a/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp b/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp index f80454e46..e79e593bf 100644 --- a/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp @@ -196,11 +196,8 @@ void MapRenderer::requestSnapshot(SnapshotCallback callback) { void MapRenderer::resetRenderer() { renderer.reset(); -#if MLN_RENDER_BACKEND_OPENGL - // GL requires the context managed by the java surface for cleanup - // Vulkan resources can be released on any thread (finalizer in this case) backend.reset(); -#endif + window.reset(); swapBehaviorFlush = false; } @@ -316,7 +313,6 @@ void MapRenderer::onRendererReset(JNIEnv&) { // needs to be called on GL thread void MapRenderer::onSurfaceDestroyed(JNIEnv&) { resetRenderer(); - window.reset(); } void MapRenderer::setSwapBehaviorFlush(JNIEnv&, jboolean flush) { diff --git a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/renderer/textureview/TextureViewRenderThread.java b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/renderer/textureview/TextureViewRenderThread.java index 11bddf38f..8a0ebf10d 100644 --- a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/renderer/textureview/TextureViewRenderThread.java +++ b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/renderer/textureview/TextureViewRenderThread.java @@ -85,7 +85,7 @@ abstract class TextureViewRenderThread extends Thread implements TextureView.Sur this.requestRender = false; lock.notifyAll(); - while (this.hasNativeSurface) { + while (this.hasNativeSurface && !this.exited) { try { lock.wait(); } catch (InterruptedException ex) { diff --git a/platform/android/MapLibreAndroid/src/vulkan/java/org/maplibre/android/maps/renderer/textureview/VulkanTextureViewRenderThread.java b/platform/android/MapLibreAndroid/src/vulkan/java/org/maplibre/android/maps/renderer/textureview/VulkanTextureViewRenderThread.java index a77dcebc5..061dd39d6 100644 --- a/platform/android/MapLibreAndroid/src/vulkan/java/org/maplibre/android/maps/renderer/textureview/VulkanTextureViewRenderThread.java +++ b/platform/android/MapLibreAndroid/src/vulkan/java/org/maplibre/android/maps/renderer/textureview/VulkanTextureViewRenderThread.java @@ -16,14 +16,12 @@ public class VulkanTextureViewRenderThread extends TextureViewRenderThread { } void cleanup() { - if (surface == null) { - return; + if (surface != null) { + mapRenderer.onSurfaceDestroyed(); + surface.release(); + surface = null; } - mapRenderer.onSurfaceDestroyed(); - surface.release(); - surface = null; - hasNativeSurface = false; } @@ -56,14 +54,17 @@ public class VulkanTextureViewRenderThread extends TextureViewRenderThread { } if (this.destroySurface) { - surface = null; destroySurface = true; + if (surface != null) { + surface.release(); + surface = null; + } + this.destroySurface = false; break; } - if (surfaceTexture != null && !paused && requestRender - && (surface == null || this.sizeChanged)) { + if (surfaceTexture != null && !paused && requestRender) { w = width; h = height; @@ -87,10 +88,6 @@ public class VulkanTextureViewRenderThread extends TextureViewRenderThread { break; } - if (requestRender && !paused) { - break; - } - // Wait until needed lock.wait(); @@ -113,11 +110,11 @@ public class VulkanTextureViewRenderThread extends TextureViewRenderThread { if (destroySurface) { mapRenderer.onSurfaceDestroyed(); - destroySurface = false; synchronized (lock) { this.hasNativeSurface = false; lock.notifyAll(); } + destroySurface = false; continue; } diff --git a/platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/MapLibreApplication.kt b/platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/MapLibreApplication.kt index 9dd668e80..4968be903 100644 --- a/platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/MapLibreApplication.kt +++ b/platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/MapLibreApplication.kt @@ -49,6 +49,7 @@ open class MapLibreApplication : MultiDexApplication() { StrictMode.setVmPolicy( VmPolicy.Builder() .detectLeakedSqlLiteObjects() + .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build() diff --git a/platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/ViewPagerActivity.kt b/platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/ViewPagerActivity.kt index 73d307b35..d9b23ec50 100644 --- a/platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/ViewPagerActivity.kt +++ b/platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/fragment/ViewPagerActivity.kt @@ -48,7 +48,7 @@ class ViewPagerActivity : AppCompatActivity() { override fun getItem(position: Int): androidx.fragment.app.Fragment { val options = MapLibreMapOptions.createFromAttributes(context) - options.textureMode(true) + options.textureMode(false) options.camera( CameraPosition.Builder() .zoom(3.0) diff --git a/platform/android/buildSrc/src/main/kotlin/maplibre.download-vulkan-validation.gradle.kts b/platform/android/buildSrc/src/main/kotlin/maplibre.download-vulkan-validation.gradle.kts index a74f8759b..df936de58 100644 --- a/platform/android/buildSrc/src/main/kotlin/maplibre.download-vulkan-validation.gradle.kts +++ b/platform/android/buildSrc/src/main/kotlin/maplibre.download-vulkan-validation.gradle.kts @@ -18,7 +18,7 @@ import java.net.URL */ // Define the validation layer version, with a default value. -var vvlVersion = "1.4.313.0" +var vvlVersion = "1.4.341.0" if (extra.has("vvl_version")) { vvlVersion = extra["vvl_version"] as String }