diff --git a/include/mbgl/renderer/renderer.hpp b/include/mbgl/renderer/renderer.hpp index 71771b982..4d2e79363 100644 --- a/include/mbgl/renderer/renderer.hpp +++ b/include/mbgl/renderer/renderer.hpp @@ -113,6 +113,10 @@ public: void reduceMemoryUse(); void clearData(); +#if MLN_RENDER_BACKEND_OPENGL + void enableAndroidEmulatorGoldfishMitigation(bool enable); +#endif + private: class Impl; std::unique_ptr impl; diff --git a/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp b/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp index fc235a67f..9fd889e05 100644 --- a/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp @@ -13,6 +13,27 @@ #include "android_renderer_backend.hpp" #include "map_renderer_runnable.hpp" +#if MLN_RENDER_BACKEND_OPENGL +#include + +namespace { +std::string androidSysProp(const char* key) { + assert(strlen(key) < PROP_NAME_MAX); + if (__system_property_find(key) == nullptr) { + return ""; + } + char prop[PROP_VALUE_MAX + 1]; + __system_property_get(key, prop); + return prop; +} + +bool inEmulator() { + return androidSysProp("ro.kernel.qemu") == "1" || androidSysProp("ro.boot.qemu") == "1" || + androidSysProp("ro.hardware.egl") == "emulation"; +} +} // namespace +#endif + namespace mbgl { namespace android { @@ -232,6 +253,14 @@ void MapRenderer::onSurfaceCreated(JNIEnv& env, const jni::Object(backend->getImpl(), pixelRatio, localIdeographFontFamily); rendererRef = std::make_unique>(*renderer, mailboxData.getMailbox()); +#if MLN_RENDER_BACKEND_OPENGL + // If we're running the emulator with the OpenGL backend, we're going to crash eventually, + // unless we enable this mitigation. + if (inEmulator()) { + renderer->enableAndroidEmulatorGoldfishMitigation(true); + } +#endif + backend->setSwapBehavior(swapBehaviorFlush ? gfx::Renderable::SwapBehaviour::Flush : gfx::Renderable::SwapBehaviour::NoFlush); diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.hpp b/src/mbgl/renderer/layers/render_heatmap_layer.hpp index 7f0419192..4c74305d7 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.hpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.hpp @@ -67,6 +67,7 @@ private: /// Remove all the drawables for tiles /// @return The number of drawables actually removed. std::size_t removeAllDrawables() override; + #endif // Paint properties diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index a1e483313..380e2dd41 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -98,6 +98,10 @@ public: const std::shared_ptr&, const RenderTree&, UniqueChangeRequestVec&) override; + + /// Remove all the drawables for tiles + std::size_t removeAllDrawables() override; + #endif // MLN_DRAWABLE_RENDERER protected: @@ -120,8 +124,6 @@ protected: /// Remove all drawables for the tile from the layer group std::size_t removeTile(RenderPass, const OverscaledTileID&) override; - /// Remove all the drawables for tiles - std::size_t removeAllDrawables() override; #endif // MLN_DRAWABLE_RENDERER private: diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index be8d6da94..417d17503 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -191,6 +191,9 @@ public: /// Returns the current renderability mode of the layer bool isLayerRenderable() const noexcept { return isRenderable; } + + /// Remove all the drawables for tiles + virtual std::size_t removeAllDrawables(); #endif using Dependency = style::expression::Dependency; @@ -247,9 +250,6 @@ protected: /// @return The number of drawables actually removed. virtual std::size_t removeTile(RenderPass, const OverscaledTileID&); - /// Remove all the drawables for tiles - virtual std::size_t removeAllDrawables(); - /// Update `renderTileIDs` from `renderTiles` void updateRenderTileIDs(); diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index c9762831a..83cb534b4 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -983,6 +983,13 @@ void RenderOrchestrator::updateLayers(gfx::ShaderRegistry& shaders, for (const auto& item : items) { auto& renderLayer = item.layer.get(); +#if MLN_RENDER_BACKEND_OPENGL + // Android Emulator: Goldfish is *very* broken. This will prevent a crash + // inside the GL translation layer at the cost of emulator performance. + if (androidGoldfishMitigationEnabled) { + renderLayer.removeAllDrawables(); + } +#endif renderLayer.update(shaders, context, state, updateParameters, renderTree, changes); } addChanges(changes); diff --git a/src/mbgl/renderer/render_orchestrator.hpp b/src/mbgl/renderer/render_orchestrator.hpp index 5065b189a..132c75996 100644 --- a/src/mbgl/renderer/render_orchestrator.hpp +++ b/src/mbgl/renderer/render_orchestrator.hpp @@ -61,6 +61,10 @@ public: const std::optional& localFontFamily_); ~RenderOrchestrator() override; +#if MLN_RENDER_BACKEND_OPENGL + void enableAndroidEmulatorGoldfishMitigation(bool enable) { androidGoldfishMitigationEnabled = enable; } +#endif + void markContextLost() { contextLost = true; }; // TODO: Introduce RenderOrchestratorObserver. void setObserver(RendererObserver*); @@ -220,6 +224,10 @@ private: bool placedSymbolDataCollected = false; bool tileCacheEnabled = true; +#if MLN_RENDER_BACKEND_OPENGL + bool androidGoldfishMitigationEnabled{false}; +#endif + // Vectors with reserved capacity of layerImpls->size() to avoid // reallocation on each frame. std::vector> filteredLayersForSource; diff --git a/src/mbgl/renderer/renderer.cpp b/src/mbgl/renderer/renderer.cpp index 0df78b071..611144d2a 100644 --- a/src/mbgl/renderer/renderer.cpp +++ b/src/mbgl/renderer/renderer.cpp @@ -152,4 +152,10 @@ void Renderer::clearData() { impl->orchestrator.clearData(); } +#if MLN_RENDER_BACKEND_OPENGL +void Renderer::enableAndroidEmulatorGoldfishMitigation(bool enable) { + impl->orchestrator.enableAndroidEmulatorGoldfishMitigation(enable); +} +#endif + } // namespace mbgl