From 331c569830a1d90d265364c23a6384ef3f78d335 Mon Sep 17 00:00:00 2001 From: flutteractionsbot <154381524+flutteractionsbot@users.noreply.github.com> Date: Mon, 7 Jul 2025 15:00:17 -0700 Subject: [PATCH] [CP-stable][Impeller] Make ContextVK hash values globally unique (#171239) This pull request is created by [automatic cherry pick workflow](https://github.com/flutter/flutter/blob/main/docs/releases/Flutter-Cherrypick-Process.md#automatically-creates-a-cherry-pick-request) Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request. ### Issue Link: What is the link to the issue this cherry-pick is addressing? https://github.com/flutter/flutter/issues/170141 ### Changelog Description: Explain this cherry pick in one line that is accessible to most Flutter developers. See [best practices](https://github.com/flutter/flutter/blob/main/docs/releases/Hotfix-Documentation-Best-Practices.md) for examples Fixes an issue in the Impeller Vulkan back end that can cause crashes when transitioning between different Android activities that use Flutter. ### Impact Description: What is the impact (ex. visual jank on Samsung phones, app crash, cannot ship an iOS app)? Does it impact development (ex. flutter doctor crashes when Android Studio is installed), or the shipping production app (the app crashes on launch) Potential crash in apps with multiple Android activities running Flutter with Impeller/Vulkan. ### Workaround: Is there a workaround for this issue? Disable Impeller ### Risk: What is the risk level of this cherry-pick? ### Test Coverage: Are you confident that your fix is well-tested by automated tests? ### Validation Steps: What are the steps to validate that this fix works? The `appShortcutLaunchActivityAfterStarting` test for the `quick_actions_android` plugin will no longer crash on Firebase Test Lab after this fix is applied. I don't know of a simpler way to manually verify the fix. --- .../renderer/backend/vulkan/context_vk.cc | 6 ++---- .../backend/vulkan/context_vk_unittests.cc | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc index a9a42ad35a..d75db4942b 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc @@ -119,11 +119,9 @@ size_t ContextVK::ChooseThreadCountForWorkers(size_t hardware_concurrency) { } namespace { -thread_local uint64_t tls_context_count = 0; +std::atomic_uint64_t context_count = 0; uint64_t CalculateHash(void* ptr) { - // You could make a context once per nanosecond for 584 years on one thread - // before this overflows. - return ++tls_context_count; + return context_count.fetch_add(1); } } // namespace diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk_unittests.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk_unittests.cc index 3de93ec63e..61c0d2bee1 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk_unittests.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk_unittests.cc @@ -392,5 +392,21 @@ TEST(ContextVKTest, AHBSwapchainCapabilitiesCanBeMissing) { } // namespace impeller +TEST(ContextVKTest, HashIsUniqueAcrossThreads) { + uint64_t hash1, hash2; + std::thread thread1([&]() { + auto context = MockVulkanContextBuilder().Build(); + hash1 = context->GetHash(); + }); + std::thread thread2([&]() { + auto context = MockVulkanContextBuilder().Build(); + hash2 = context->GetHash(); + }); + thread1.join(); + thread2.join(); + + EXPECT_NE(hash1, hash2); +} + } // namespace testing } // namespace impeller