Skip to content

[Impeller] Dispose thread local caches on each frame when using GPUSurfaceVulkanImpeller with a delegate - #182265

Merged
auto-submit[bot] merged 3 commits into
flutter:masterfrom
jason-simmons:vulkan_delegate_thread_leak
Feb 13, 2026
Merged

auto-submit[bot] merged 3 commits into
flutter:masterfrom
jason-simmons:vulkan_delegate_thread_leak

Conversation

@jason-simmons

Copy link
Copy Markdown
Member

The Impeller Vulkan back end caches command pools in thread-local storage. These caches can grow unbounded unless the embedder calls ContextVK::DisposeThreadLocalCachedResources()

If the GPUSurfaceVulkanImpeller does not have a delegate, then AcquireFrame will invoke DisposeThreadLocalCachedResources through its call to SurfaceContextVK::AcquireNextSurface.

With a delegate, AcquireFrame follows a different code path that must explicitly call DisposeThreadLocalCachedResources.

@github-actions github-actions Bot added the engine flutter/engine related. See also e: labels. label Feb 11, 2026
@jason-simmons

Copy link
Copy Markdown
Member Author

Noticed this memory leak while looking at #181966 / #181967

cc @RickyvdBerg - if you are using the Impeller/Vulkan back end with the embedder and GPUSurfaceVulkanImpeller delegates, then you will also want this fix.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses a potential resource leak in the Impeller Vulkan backend by ensuring that thread-local caches are disposed on each frame when GPUSurfaceVulkanImpeller is used with a delegate. The security audit could not identify any vulnerabilities as the provided files were empty, preventing a meaningful analysis. Overall, the changes are logical and well-implemented, including the correct addition of a call to DisposeThreadLocalCachedResources and the introduction of a new unit test to verify this behavior.

Comment on lines +62 to +76
auto context = impeller::ContextVK::Create(std::move(context_settings));

TestGPUSurfaceVulkanDelegate delegate;

std::unique_ptr<Surface> surface =
std::make_unique<GPUSurfaceVulkanImpeller>(&delegate, context);

// Add a command pool to the global map.
auto pool = context->GetCommandPoolRecycler()->Get();
EXPECT_EQ(impeller::CommandPoolRecyclerVK::GetGlobalPoolCount(*context), 1);

// Check that AcquireFrame disposes thread local resources and removes
// the pool from the global map.
auto frame = surface->AcquireFrame(DlISize(100, 100));
EXPECT_EQ(impeller::CommandPoolRecyclerVK::GetGlobalPoolCount(*context), 0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The test would be more robust if it included assertions to verify that the objects (context, surface, pool, frame) are created successfully before they are used. This ensures that the test fails early and clearly if setup fails, rather than potentially crashing or failing with a less specific error later on.

  auto context = impeller::ContextVK::Create(std::move(context_settings));
  ASSERT_TRUE(context && context->IsValid());

  TestGPUSurfaceVulkanDelegate delegate;

  std::unique_ptr<Surface> surface =
      std::make_unique<GPUSurfaceVulkanImpeller>(&delegate, context);
  ASSERT_TRUE(surface->IsValid());

  // Add a command pool to the global map.
  auto pool = context->GetCommandPoolRecycler()->Get();
  ASSERT_NE(pool, nullptr);
  EXPECT_EQ(impeller::CommandPoolRecyclerVK::GetGlobalPoolCount(*context), 1);

  // Check that AcquireFrame disposes thread local resources and removes
  // the pool from the global map.
  auto frame = surface->AcquireFrame(DlISize(100, 100));
  ASSERT_NE(frame, nullptr);
  EXPECT_EQ(impeller::CommandPoolRecyclerVK::GetGlobalPoolCount(*context), 0);

@gaaclarke gaaclarke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good and test looks good. I'd just like to see this incorporated as part of impeller_unittests instead of adding yet another executable.

Comment thread engine/src/flutter/shell/gpu/BUILD.gn Outdated
}
}

if (impeller_enable_vulkan) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add these tests as part of impeller_unittests instead of making a new executable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Impeller is mostly independent of the rest of Flutter.

I'd prefer to avoid having the impeller_unittests binary incorporate code from the flutter/shell/gpu tree.

This PR adds a shell/gpu test binary for Vulkan similar to the existing one for Metal.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, not adding it to impeller_unittests sounds good. Can we add this test to the existing metal one then?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gpu_surface_metal_unittests in https://github.com/flutter/flutter/blob/master/engine/src/flutter/shell/gpu/BUILD.gn is specific to Apple platforms.

The Vulkan test should be buildable on the platforms that support Vulkan/SwiftShader.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I'm thinking we do like what we do in impeller_unittests where we only link in tests that are applicable to the testing platform. So the executable will be gpu_surface_unittests, if you are building for macos you will build and link in the metal tests, on linux you won't. We can have TEST_P tests if we want the same test across multiple backens.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merged the shell/gpu test binaries - PTAL

@gaaclarke
gaaclarke self-requested a review February 12, 2026 15:39

@gaaclarke gaaclarke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks jason! Our testing setup for the engine is pretty complicated, I'm operating under the theory that the less testing executables there are the easier it is for people to find and execute tests. When there is separate binaries too it's easier for them to drift too. Hopefully his helps.

…rfaceVulkanImpeller with a delegate

The Impeller Vulkan back end caches command pools in thread-local storage.  These caches can grow unbounded unless the embedder calls ContextVK::DisposeThreadLocalCachedResources()

If the GPUSurfaceVulkanImpeller does not have a delegate, then AcquireFrame will invoke DisposeThreadLocalCachedResources through its call to SurfaceContextVK::AcquireNextSurface.

With a delegate, AcquireFrame follows a different code path that must explicitly call DisposeThreadLocalCachedResources.
@jason-simmons
jason-simmons force-pushed the vulkan_delegate_thread_leak branch from 1102705 to b572a37 Compare February 13, 2026 15:28
@jason-simmons jason-simmons added the autosubmit Merge PR when tree becomes green via auto submit App label Feb 13, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Feb 13, 2026
Merged via the queue into flutter:master with commit 2cef9c5 Feb 13, 2026
182 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Feb 13, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 13, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 14, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 14, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 14, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 14, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 15, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 15, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 15, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 16, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 16, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 16, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 17, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 17, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 17, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Feb 17, 2026
Roll Flutter from 9bda20a11f1e to 6e4a481bdf27 (103 revisions)

flutter/flutter@9bda20a...6e4a481

2026-02-17 [email protected] Fix iOS CI tests for Xcode 26 Swift compatibility (flutter/flutter#182132)
2026-02-17 [email protected] Revert "[Android] Add mechanism for setting Android engine flags via … (flutter/flutter#182388)
2026-02-17 [email protected] Roll Skia from 4ed9faf843e6 to dfe78d132e24 (1 revision) (flutter/flutter#182485)
2026-02-17 [email protected] Roll Skia from ff0af46bf172 to 4ed9faf843e6 (2 revisions) (flutter/flutter#182483)
2026-02-17 [email protected] Roll Skia from 24c7b6f5760f to ff0af46bf172 (1 revision) (flutter/flutter#182481)
2026-02-16 [email protected] Roll Dart SDK from ff57548fcf54 to 44895e617182 (1 revision) (flutter/flutter#182479)
2026-02-16 [email protected] Roll Fuchsia Linux SDK from YND8TyaxKkkkEvlD9... to mcN42vw48OPH3JDNm... (flutter/flutter#182478)
2026-02-16 [email protected] Roll Dart SDK from c819ebe0cbe3 to ff57548fcf54 (1 revision) (flutter/flutter#182472)
2026-02-16 [email protected] feat: add routes support in TestWidgetsApp (flutter/flutter#181695)
2026-02-16 [email protected] Roll Skia from 5c8a6641902f to 24c7b6f5760f (1 revision) (flutter/flutter#182467)
2026-02-16 [email protected] Roll Skia from 94d5d5e5f785 to 5c8a6641902f (6 revisions) (flutter/flutter#182463)
2026-02-16 [email protected] Roll Dart SDK from f2289e13a20a to c819ebe0cbe3 (1 revision) (flutter/flutter#182462)
2026-02-15 [email protected] Roll Dart SDK from 294e6e248512 to f2289e13a20a (1 revision) (flutter/flutter#182448)
2026-02-15 [email protected] Roll Skia from b7cea4cbe546 to 94d5d5e5f785 (1 revision) (flutter/flutter#182446)
2026-02-15 [email protected] Roll Fuchsia Linux SDK from pkyhAZ3sQZDzeNZym... to YND8TyaxKkkkEvlD9... (flutter/flutter#182445)
2026-02-15 [email protected] Roll Skia from a3a82d359a7b to b7cea4cbe546 (1 revision) (flutter/flutter#182439)
2026-02-15 [email protected] Roll Skia from a147ae2d4adc to a3a82d359a7b (1 revision) (flutter/flutter#182435)
2026-02-15 [email protected] Roll Dart SDK from f82ec89435f5 to 294e6e248512 (1 revision) (flutter/flutter#182432)
2026-02-14 [email protected] Roll Skia from 91d158b0a61e to a147ae2d4adc (2 revisions) (flutter/flutter#182424)
2026-02-14 [email protected] Roll Fuchsia Linux SDK from V30FBkJySjFKXwVjW... to pkyhAZ3sQZDzeNZym... (flutter/flutter#182423)
2026-02-14 [email protected] Roll Skia from e5a18f8f0d4a to 91d158b0a61e (1 revision) (flutter/flutter#182422)
2026-02-14 [email protected] Roll Dart SDK from 7a2a28dbd0d4 to f82ec89435f5 (2 revisions) (flutter/flutter#182414)
2026-02-14 [email protected] Roll Skia from befeec673f1b to e5a18f8f0d4a (1 revision) (flutter/flutter#182412)
2026-02-14 [email protected] Roll Skia from 7dc3ba9b1d90 to befeec673f1b (1 revision) (flutter/flutter#182408)
2026-02-14 [email protected] [Web] Fix IME and selection by syncing more text styles (flutter/flutter#180436)
2026-02-14 [email protected] Roll Skia from bb69b5b71b4f to 7dc3ba9b1d90 (2 revisions) (flutter/flutter#182401)
2026-02-14 [email protected] Disable multithread opengles, enables remaining fragment shader tests (flutter/flutter#182384)
2026-02-14 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Standardize on Test* widgets in *_tester.dart files (#182395)" (flutter/flutter#182406)
2026-02-14 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Fix cross imports for all Cupertino tests (#181634)" (flutter/flutter#182404)
2026-02-13 [email protected] Add await to tester.pump callsites (flutter/flutter#182398)
2026-02-13 [email protected] refactor: Centralize table formatting logic into a new `formatTable` utility function. (flutter/flutter#182196)
2026-02-13 [email protected] Adds impeller backend to golden workspace name (flutter/flutter#182387)
2026-02-13 [email protected] Standardize on Test* widgets in *_tester.dart files (flutter/flutter#182395)
2026-02-13 [email protected] Remove Material dependency from transformed_scrollable_test.dart (flutter/flutter#182141)
2026-02-13 [email protected] Fix cross imports for all Cupertino tests (flutter/flutter#181634)
2026-02-13 [email protected] remove MaterialApp import from raw_radio_test.dart (flutter/flutter#181721)
2026-02-13 [email protected] Roll Skia from e2991aa99710 to bb69b5b71b4f (37 revisions) (flutter/flutter#182390)
2026-02-13 [email protected] Turns on most of fragment_shader_test.dart for opengles (flutter/flutter#182229)
2026-02-13 [email protected] Update `CHANGELOG` for 3.41.1 release (flutter/flutter#182393)
2026-02-13 [email protected] Remove Material dependency from semantics_keep_alive_offstage_test.dart (flutter/flutter#182211)
2026-02-13 [email protected] Update iOS/macOS plugin template to add dependency on FlutterFramework (flutter/flutter#181416)
2026-02-13 [email protected] Add plugin dependencies to Add to App FlutterPluginRegistrant (flutter/flutter#182304)
2026-02-13 [email protected] Preparation to add contentTextStyle flag to SimpleDialog. (flutter/flutter#182200)
2026-02-13 [email protected] Roll Packages from af1d610 to 09104b0 (4 revisions) (flutter/flutter#182383)
2026-02-13 [email protected] Roll Dart SDK from de5915148fde to 7a2a28dbd0d4 (2 revisions) (flutter/flutter#182380)
2026-02-13 [email protected] [Impeller] Dispose thread local caches on each frame when using GPUSurfaceVulkanImpeller with a delegate (flutter/flutter#182265)
...
rickhohler pushed a commit to rickhohler/flutter that referenced this pull request Feb 19, 2026
…rfaceVulkanImpeller with a delegate (flutter#182265)

The Impeller Vulkan back end caches command pools in thread-local
storage. These caches can grow unbounded unless the embedder calls
ContextVK::DisposeThreadLocalCachedResources()

If the GPUSurfaceVulkanImpeller does not have a delegate, then
AcquireFrame will invoke DisposeThreadLocalCachedResources through its
call to SurfaceContextVK::AcquireNextSurface.

With a delegate, AcquireFrame follows a different code path that must
explicitly call DisposeThreadLocalCachedResources.
RickyvdBerg added a commit to avio-os/avio-flutter that referenced this pull request Mar 5, 2026
…path

The Impeller Vulkan backend caches command pools and descriptor pools
in thread-local storage. These caches grow unbounded unless
DisposeThreadLocalCachedResources() is called each frame.

PRs flutter#182265 and flutter#182402 fixed this for GPUSurfaceVulkanImpeller (delegate
path) and libImpeller (C API) respectively, but the Flutter Embedder API
compositor path through EmbedderExternalViewEmbedder was missed.

EmbedderExternalViewEmbedder::SubmitFlutterView calls builder.Render()
which calls EmbedderExternalView::Render() which calls the
RenderToTarget overload that does not dispose cached resources. This
causes linear memory growth from leaked VkCommandBuffers (~20-40KB each)
and VkDescriptorPools (~40-80KB each, one per ~80 frames).

Add DisposeThreadLocalCachedResources() after builder.Render() in
SubmitFlutterView, matching the pattern used in the other two paths.
The call goes through the base impeller::Context interface so it is a
no-op on non-Vulkan backends.

Related to flutter#182265
Related to flutter#182402
okorohelijah pushed a commit to okorohelijah/packages that referenced this pull request Mar 26, 2026
…er#11041)

Roll Flutter from 9bda20a11f1e to 6e4a481bdf27 (103 revisions)

flutter/flutter@9bda20a...6e4a481

2026-02-17 [email protected] Fix iOS CI tests for Xcode 26 Swift compatibility (flutter/flutter#182132)
2026-02-17 [email protected] Revert "[Android] Add mechanism for setting Android engine flags via … (flutter/flutter#182388)
2026-02-17 [email protected] Roll Skia from 4ed9faf843e6 to dfe78d132e24 (1 revision) (flutter/flutter#182485)
2026-02-17 [email protected] Roll Skia from ff0af46bf172 to 4ed9faf843e6 (2 revisions) (flutter/flutter#182483)
2026-02-17 [email protected] Roll Skia from 24c7b6f5760f to ff0af46bf172 (1 revision) (flutter/flutter#182481)
2026-02-16 [email protected] Roll Dart SDK from ff57548fcf54 to 44895e617182 (1 revision) (flutter/flutter#182479)
2026-02-16 [email protected] Roll Fuchsia Linux SDK from YND8TyaxKkkkEvlD9... to mcN42vw48OPH3JDNm... (flutter/flutter#182478)
2026-02-16 [email protected] Roll Dart SDK from c819ebe0cbe3 to ff57548fcf54 (1 revision) (flutter/flutter#182472)
2026-02-16 [email protected] feat: add routes support in TestWidgetsApp (flutter/flutter#181695)
2026-02-16 [email protected] Roll Skia from 5c8a6641902f to 24c7b6f5760f (1 revision) (flutter/flutter#182467)
2026-02-16 [email protected] Roll Skia from 94d5d5e5f785 to 5c8a6641902f (6 revisions) (flutter/flutter#182463)
2026-02-16 [email protected] Roll Dart SDK from f2289e13a20a to c819ebe0cbe3 (1 revision) (flutter/flutter#182462)
2026-02-15 [email protected] Roll Dart SDK from 294e6e248512 to f2289e13a20a (1 revision) (flutter/flutter#182448)
2026-02-15 [email protected] Roll Skia from b7cea4cbe546 to 94d5d5e5f785 (1 revision) (flutter/flutter#182446)
2026-02-15 [email protected] Roll Fuchsia Linux SDK from pkyhAZ3sQZDzeNZym... to YND8TyaxKkkkEvlD9... (flutter/flutter#182445)
2026-02-15 [email protected] Roll Skia from a3a82d359a7b to b7cea4cbe546 (1 revision) (flutter/flutter#182439)
2026-02-15 [email protected] Roll Skia from a147ae2d4adc to a3a82d359a7b (1 revision) (flutter/flutter#182435)
2026-02-15 [email protected] Roll Dart SDK from f82ec89435f5 to 294e6e248512 (1 revision) (flutter/flutter#182432)
2026-02-14 [email protected] Roll Skia from 91d158b0a61e to a147ae2d4adc (2 revisions) (flutter/flutter#182424)
2026-02-14 [email protected] Roll Fuchsia Linux SDK from V30FBkJySjFKXwVjW... to pkyhAZ3sQZDzeNZym... (flutter/flutter#182423)
2026-02-14 [email protected] Roll Skia from e5a18f8f0d4a to 91d158b0a61e (1 revision) (flutter/flutter#182422)
2026-02-14 [email protected] Roll Dart SDK from 7a2a28dbd0d4 to f82ec89435f5 (2 revisions) (flutter/flutter#182414)
2026-02-14 [email protected] Roll Skia from befeec673f1b to e5a18f8f0d4a (1 revision) (flutter/flutter#182412)
2026-02-14 [email protected] Roll Skia from 7dc3ba9b1d90 to befeec673f1b (1 revision) (flutter/flutter#182408)
2026-02-14 [email protected] [Web] Fix IME and selection by syncing more text styles (flutter/flutter#180436)
2026-02-14 [email protected] Roll Skia from bb69b5b71b4f to 7dc3ba9b1d90 (2 revisions) (flutter/flutter#182401)
2026-02-14 [email protected] Disable multithread opengles, enables remaining fragment shader tests (flutter/flutter#182384)
2026-02-14 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Standardize on Test* widgets in *_tester.dart files (#182395)" (flutter/flutter#182406)
2026-02-14 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Fix cross imports for all Cupertino tests (#181634)" (flutter/flutter#182404)
2026-02-13 [email protected] Add await to tester.pump callsites (flutter/flutter#182398)
2026-02-13 [email protected] refactor: Centralize table formatting logic into a new `formatTable` utility function. (flutter/flutter#182196)
2026-02-13 [email protected] Adds impeller backend to golden workspace name (flutter/flutter#182387)
2026-02-13 [email protected] Standardize on Test* widgets in *_tester.dart files (flutter/flutter#182395)
2026-02-13 [email protected] Remove Material dependency from transformed_scrollable_test.dart (flutter/flutter#182141)
2026-02-13 [email protected] Fix cross imports for all Cupertino tests (flutter/flutter#181634)
2026-02-13 [email protected] remove MaterialApp import from raw_radio_test.dart (flutter/flutter#181721)
2026-02-13 [email protected] Roll Skia from e2991aa99710 to bb69b5b71b4f (37 revisions) (flutter/flutter#182390)
2026-02-13 [email protected] Turns on most of fragment_shader_test.dart for opengles (flutter/flutter#182229)
2026-02-13 [email protected] Update `CHANGELOG` for 3.41.1 release (flutter/flutter#182393)
2026-02-13 [email protected] Remove Material dependency from semantics_keep_alive_offstage_test.dart (flutter/flutter#182211)
2026-02-13 [email protected] Update iOS/macOS plugin template to add dependency on FlutterFramework (flutter/flutter#181416)
2026-02-13 [email protected] Add plugin dependencies to Add to App FlutterPluginRegistrant (flutter/flutter#182304)
2026-02-13 [email protected] Preparation to add contentTextStyle flag to SimpleDialog. (flutter/flutter#182200)
2026-02-13 [email protected] Roll Packages from af1d610 to 09104b0 (4 revisions) (flutter/flutter#182383)
2026-02-13 [email protected] Roll Dart SDK from de5915148fde to 7a2a28dbd0d4 (2 revisions) (flutter/flutter#182380)
2026-02-13 [email protected] [Impeller] Dispose thread local caches on each frame when using GPUSurfaceVulkanImpeller with a delegate (flutter/flutter#182265)
...
mboetger pushed a commit to mboetger/flutter that referenced this pull request Mar 26, 2026
…rfaceVulkanImpeller with a delegate (flutter#182265)

The Impeller Vulkan back end caches command pools in thread-local
storage. These caches can grow unbounded unless the embedder calls
ContextVK::DisposeThreadLocalCachedResources()

If the GPUSurfaceVulkanImpeller does not have a delegate, then
AcquireFrame will invoke DisposeThreadLocalCachedResources through its
call to SurfaceContextVK::AcquireNextSurface.

With a delegate, AcquireFrame follows a different code path that must
explicitly call DisposeThreadLocalCachedResources.
creatorpiyush pushed a commit to creatorpiyush/packages that referenced this pull request Jun 10, 2026
…er#11041)

Roll Flutter from 9bda20a11f1e to 6e4a481bdf27 (103 revisions)

flutter/flutter@9bda20a...6e4a481

2026-02-17 [email protected] Fix iOS CI tests for Xcode 26 Swift compatibility (flutter/flutter#182132)
2026-02-17 [email protected] Revert "[Android] Add mechanism for setting Android engine flags via … (flutter/flutter#182388)
2026-02-17 [email protected] Roll Skia from 4ed9faf843e6 to dfe78d132e24 (1 revision) (flutter/flutter#182485)
2026-02-17 [email protected] Roll Skia from ff0af46bf172 to 4ed9faf843e6 (2 revisions) (flutter/flutter#182483)
2026-02-17 [email protected] Roll Skia from 24c7b6f5760f to ff0af46bf172 (1 revision) (flutter/flutter#182481)
2026-02-16 [email protected] Roll Dart SDK from ff57548fcf54 to 44895e617182 (1 revision) (flutter/flutter#182479)
2026-02-16 [email protected] Roll Fuchsia Linux SDK from YND8TyaxKkkkEvlD9... to mcN42vw48OPH3JDNm... (flutter/flutter#182478)
2026-02-16 [email protected] Roll Dart SDK from c819ebe0cbe3 to ff57548fcf54 (1 revision) (flutter/flutter#182472)
2026-02-16 [email protected] feat: add routes support in TestWidgetsApp (flutter/flutter#181695)
2026-02-16 [email protected] Roll Skia from 5c8a6641902f to 24c7b6f5760f (1 revision) (flutter/flutter#182467)
2026-02-16 [email protected] Roll Skia from 94d5d5e5f785 to 5c8a6641902f (6 revisions) (flutter/flutter#182463)
2026-02-16 [email protected] Roll Dart SDK from f2289e13a20a to c819ebe0cbe3 (1 revision) (flutter/flutter#182462)
2026-02-15 [email protected] Roll Dart SDK from 294e6e248512 to f2289e13a20a (1 revision) (flutter/flutter#182448)
2026-02-15 [email protected] Roll Skia from b7cea4cbe546 to 94d5d5e5f785 (1 revision) (flutter/flutter#182446)
2026-02-15 [email protected] Roll Fuchsia Linux SDK from pkyhAZ3sQZDzeNZym... to YND8TyaxKkkkEvlD9... (flutter/flutter#182445)
2026-02-15 [email protected] Roll Skia from a3a82d359a7b to b7cea4cbe546 (1 revision) (flutter/flutter#182439)
2026-02-15 [email protected] Roll Skia from a147ae2d4adc to a3a82d359a7b (1 revision) (flutter/flutter#182435)
2026-02-15 [email protected] Roll Dart SDK from f82ec89435f5 to 294e6e248512 (1 revision) (flutter/flutter#182432)
2026-02-14 [email protected] Roll Skia from 91d158b0a61e to a147ae2d4adc (2 revisions) (flutter/flutter#182424)
2026-02-14 [email protected] Roll Fuchsia Linux SDK from V30FBkJySjFKXwVjW... to pkyhAZ3sQZDzeNZym... (flutter/flutter#182423)
2026-02-14 [email protected] Roll Skia from e5a18f8f0d4a to 91d158b0a61e (1 revision) (flutter/flutter#182422)
2026-02-14 [email protected] Roll Dart SDK from 7a2a28dbd0d4 to f82ec89435f5 (2 revisions) (flutter/flutter#182414)
2026-02-14 [email protected] Roll Skia from befeec673f1b to e5a18f8f0d4a (1 revision) (flutter/flutter#182412)
2026-02-14 [email protected] Roll Skia from 7dc3ba9b1d90 to befeec673f1b (1 revision) (flutter/flutter#182408)
2026-02-14 [email protected] [Web] Fix IME and selection by syncing more text styles (flutter/flutter#180436)
2026-02-14 [email protected] Roll Skia from bb69b5b71b4f to 7dc3ba9b1d90 (2 revisions) (flutter/flutter#182401)
2026-02-14 [email protected] Disable multithread opengles, enables remaining fragment shader tests (flutter/flutter#182384)
2026-02-14 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Standardize on Test* widgets in *_tester.dart files (#182395)" (flutter/flutter#182406)
2026-02-14 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Fix cross imports for all Cupertino tests (#181634)" (flutter/flutter#182404)
2026-02-13 [email protected] Add await to tester.pump callsites (flutter/flutter#182398)
2026-02-13 [email protected] refactor: Centralize table formatting logic into a new `formatTable` utility function. (flutter/flutter#182196)
2026-02-13 [email protected] Adds impeller backend to golden workspace name (flutter/flutter#182387)
2026-02-13 [email protected] Standardize on Test* widgets in *_tester.dart files (flutter/flutter#182395)
2026-02-13 [email protected] Remove Material dependency from transformed_scrollable_test.dart (flutter/flutter#182141)
2026-02-13 [email protected] Fix cross imports for all Cupertino tests (flutter/flutter#181634)
2026-02-13 [email protected] remove MaterialApp import from raw_radio_test.dart (flutter/flutter#181721)
2026-02-13 [email protected] Roll Skia from e2991aa99710 to bb69b5b71b4f (37 revisions) (flutter/flutter#182390)
2026-02-13 [email protected] Turns on most of fragment_shader_test.dart for opengles (flutter/flutter#182229)
2026-02-13 [email protected] Update `CHANGELOG` for 3.41.1 release (flutter/flutter#182393)
2026-02-13 [email protected] Remove Material dependency from semantics_keep_alive_offstage_test.dart (flutter/flutter#182211)
2026-02-13 [email protected] Update iOS/macOS plugin template to add dependency on FlutterFramework (flutter/flutter#181416)
2026-02-13 [email protected] Add plugin dependencies to Add to App FlutterPluginRegistrant (flutter/flutter#182304)
2026-02-13 [email protected] Preparation to add contentTextStyle flag to SimpleDialog. (flutter/flutter#182200)
2026-02-13 [email protected] Roll Packages from af1d610 to 09104b0 (4 revisions) (flutter/flutter#182383)
2026-02-13 [email protected] Roll Dart SDK from de5915148fde to 7a2a28dbd0d4 (2 revisions) (flutter/flutter#182380)
2026-02-13 [email protected] [Impeller] Dispose thread local caches on each frame when using GPUSurfaceVulkanImpeller with a delegate (flutter/flutter#182265)
...
RickyvdBerg added a commit to avio-os/avio-flutter that referenced this pull request Jul 23, 2026
…path

The Impeller Vulkan backend caches command pools and descriptor pools
in thread-local storage. These caches grow unbounded unless
DisposeThreadLocalCachedResources() is called each frame.

PRs flutter#182265 and flutter#182402 fixed this for GPUSurfaceVulkanImpeller (delegate
path) and libImpeller (C API) respectively, but the Flutter Embedder API
compositor path through EmbedderExternalViewEmbedder was missed.

EmbedderExternalViewEmbedder::SubmitFlutterView calls builder.Render()
which calls EmbedderExternalView::Render() which calls the
RenderToTarget overload that does not dispose cached resources. This
causes linear memory growth from leaked VkCommandBuffers (~20-40KB each)
and VkDescriptorPools (~40-80KB each, one per ~80 frames).

Add DisposeThreadLocalCachedResources() after builder.Render() in
SubmitFlutterView, matching the pattern used in the other two paths.
The call goes through the base impeller::Context interface so it is a
no-op on non-Vulkan backends.

Related to flutter#182265
Related to flutter#182402
yuichi-kusakabe added a commit to automotive-grade-linux/sodev-demo-workspace-rpi that referenced this pull request Sep 25, 2026
DomA and DomU render with Vulkan through Venus -- guest Vulkan over
virtio-gpu -- in the default build, and --gpu=gl rebuilds the pre-Venus
OpenGL stack. This is the board-independent part of the lane: the Xen
and libxl changes that give a device model a host-visible window it can
share into its guest, the qemu 10.0.2-xt device model, the virglrenderer
and DomD kernel changes behind it, a newer DomD mesa, the DomD Vulkan
runtime, the guest configs, the build.sh switch, a layer for the AGL
guest, the opt-in diagnostics and the document. Each board's yaml and
hypervisor wiring are in the rpi4 and rpi5 commits of this group.

Nearly everything here is gated on the tree's own `venus`
DISTRO_FEATURE, which the board yamls set for GPU=vulkan, so in a
--gpu=gl build the Xen, qemu 7.0.0-xt and virglrenderer builds carry
nothing from this commit. The exceptions are named where they occur:
the DomD mesa pin, DomA's mesa patch, the device-model argument fixups,
which follow the qemu version rather than the lane, and --devel's
hypervisor diagnostic patch, which is not gated.

Xen and libxl: a window the device model can share

A virtio-gpu host-visible blob has to be real guest memory, not trapping
MMIO. On arm64 an emulated access is fatal rather than slow: a data
abort from a SIMD/FP access carries no valid syndrome, Xen's
decode_arm64() covers only the general-purpose load/store forms, and
Mesa's venus writes its command ring with memcpy(), so the guest's
Vulkan client dies at its first ring write ("unhandled Arm instruction
0x3d800000", measured on a Raspberry Pi 5).

4.22-0007 (xen/arch/arm/mm.c) lets a device model share its own memory
into the guest it serves. Two refusals stand in the way on 4.22. The
owner lookup, rcu_lock_remote_domain_by_id(), cannot name the caller:
DOMID_SELF gives -ESRCH and the caller's own domid -EPERM. The patch
resolves DOMID_SELF itself, as get_pg_owner() did before 4.22, and moves
the "od == d" refusal so that it still covers that case. And
xsm_map_gmfn_foreign() asks whether the domain receiving the mapping is
privileged over the page owner -- right for a control domain mapping a
guest page into itself, wrong here -- so it is skipped when the caller
owns the pages; the common code has already required the caller to be
privileged over the target. A plain context refresh of the 4.21 patch
applies with zero fuzz, compiles, and never executes.

4.22-0008 (xen/include/public/arch-arm.h) moves the guest's prefetchable
virtio-pci window from 64 MiB at 0x3a000000, where no BAR larger than
32 MiB fits, to 768 MiB at 0xc0000000, the hole between the top of
GUEST_RAM0 and 4 GiB. 0x10000000 only looks free: it is
GUEST_VPCI_ECAM_BASE/SIZE, and blob pages in the p2m never fault, so a
guest with a passthrough PCI device would read blob contents instead of
config space. The hypervisor and the toolstack share it, so it lives in
xen-common/files.

4.22-0009 (tools/libs/light/libxl_arm.c) hands that window out in
256 MiB slices instead of 8 MiB. Three fit, and every guest here has one
virtio-pci host; a guest with more hosts than slices is refused with an
error instead of being given an overlapping window. With fewer slices
than hosts the one-slice-per-host assertion goes, and a lone
BUILD_BUG_ON(VIRTIO_PCI_MAX_HOSTS < VIRTIO_PCI_MAX_PREFETCH_HOSTS) would
not do: with the old 64 MiB window the slice count truncates to zero and
8 < 0 passes. So three assertions stand in its place -- no more slices
than hosts, at least one slice, and the slice size divides the window --
and a toolstack tree without 4.22-0008 fails to build instead of
refusing every virtio-pci guest at run time.

xen-tools_4.22.bbappend lists 4.22-0008 and then 4.22-0009 under the
venus gate; each board's hypervisor bbappend lists 4.22-0007 and
4.22-0008 in the rpi4 and rpi5 commits of this group.
xen-tools_4.22.bbappend's note on ./files names 4.22-0009 among the
toolstack-only patches kept there, and no longer counts the interim
recipe's pre-patches among them: meta-xt-domx's xen-tools_4.22.bb takes
two from meta-virtualization's files/ and its refreshed tests-vpci one
from its own files/. On a Raspberry Pi 4 on 2026-09-12, with Xen 4.22,
4.22-0007, 4.22-0008 and 4.22-0009 and 128 MiB slices, the guest was
assigned its BAR out of the 0xc0000000 window, the device model shared
the blob into the guest's p2m, and a Vulkan client in DomU and a
full-Vulkan AAOS in DomA both rendered.

The window is 256 MiB, and the physmap batch is split to fit

On a Raspberry Pi 5, 8 MiB slices left a Vulkan client failing
vkAllocateMemory with VK_ERROR_OUT_OF_DEVICE_MEMORY as soon as it wanted
anything of display size, and 32 MiB was measured too small in turn:
venus takes ~25 MiB of it and a 1920x1080 swapchain fails the same way.
128 MiB then ran out on a full-Vulkan AAOS once its resident apps were
up, because every process that renders with HWUI on Venus maps its own
blocks into the window.
Measured in DomA on a Raspberry Pi 4 (1280x720, 2026-09-24): launcher
23.6, systemui 20.6, SurfaceFlinger 19.8, car settings 19.6, maps
placeholder 10.6 and rotary 9.1 MiB -- 103 MiB of 128, the 25 MiB left
split into two 11 MiB holes. A WebView playing video on top of that
fails vkAllocateMemory ("SharedContextState context lost via Skia OOM"),
and the app shows a white page or aborts with "Non owned context lost!".
With HWUI switched to GL for the same test the page renders, which
confirms the window, not the decoder or the network, is what runs out.

A WebView playing video exhausts 128 MiB, so 4.22-0009's slice is
256 MiB, and the board yamls of this group set hostmem=256M. hostmem
becomes the virtio-gpu BAR as it is, so it stays a power of two no
larger than the slice. The window is address space until a guest maps a
blob into it; what a guest does map is DomD memory.

A blob that fills a 256 MiB window is 65536 pages, one more than the
physmap hypercall can count. xen_add_to_physmap_batch.size is a uint16_t
that libxc fills in without a check, so the count wraps: Xen maps
nothing, returns success, and the guest keeps the trapping MMIO mapping
-- the SIMD-abort death, not a clean VK_ERROR_MEMORY_MAP_FAILED. With
128 MiB no blob could reach that (32768 pages at most). So qemu's 0116
issues the batch in chunks of at most UINT16_MAX pages. A chunk the
hypercall rejects is recorded as failed page by page, together with
every page after it, so the partial-batch rollback also takes out the
chunks that did go in before the region is withdrawn.

qemu 10.0.2-xt: the device model Venus needs

virtio-gpu-gl gained its venus= property in qemu 9.2, so the 7.0.0-xt
fork cannot carry Venus. meta-xt-qemu gains qemu_10.0.2.bb: the same
xen-troops fork on its v10.0.2-xt branch, with oe-core's qemu 10.2.0
recipe body reached through `require` rather than a second vendored
qemu.inc. It fetches the three meson subprojects a git tree lacks
(keycodemapdb and the berkeley softfloat/testfloat pair) at the
revisions the wrap files pin, overrides LIC_FILES_CHKSUM for the 10.0.2
license files, and turns off the guest agent and pulseaudio.
PREFERRED_VERSION_qemu, which the board yamls set per lane, picks
between the two recipes. The recipe carries eight patches:

  0114  configure: use the host python and meson, not a venv it cannot
        populate offline (oe-core's two patches, folded and rebased).
  0115  hw/arm: accept "xenpv", which libxl still passes, for the
        renamed xenpvh machine, with the PCI layout libxl publishes.
        Without it every domain that needs a qemu backend failed to be
        created: 'unsupported machine type: "xenpv"'.
  0116  hw/arm: share device-model RAM into the guest's physmap with
        XENMAPSPACE_gmfn_foreign and DOMID_SELF, so the guest accesses
        real memory with no trap. Frame numbers come from
        /proc/self/pagemap or, for a dma-buf, from the DomD kernel's
        new gntdev ioctl; when neither works the window is withdrawn
        rather than left emulated.
  0117  ui/sdl2: adopt SDL's EGLDisplay. qemu set qemu_egl_display from
        egl-headless, dbus, spice and gtk but never from sdl, and both
        guests run -display sdl,gl=es, so virglrenderer imported
        dma-bufs through GL_EXT_memory_object, which V3D does not
        implement: every import failed with EINVAL.
  0118  virtio-input-hid: send BTN_TOUCH for the tablet, the 10.0.2
        form of meta-xt-driver-domain's 7.0.0-only 0111. Android
        classifies an ABS_X/ABS_Y device as a touchscreen only when it
        also reports BTN_TOUCH, so this is what keeps DomA's touch.
        10.0.2 already advertises BTN_TOUCH; only the send side was
        missing.
  0119  vhost: do not verify vring host mappings under Xen. Mapping a
        blob drives vhost_commit(), which re-verifies every vring
        against a memory table whose Xen entries are pseudo-hvas, and
        the device model aborted with
        "Verify ring failure on region 0" as soon as Mesa created its
        first Vulkan context (RPi4, 2026-09-07, three of three
        domains). The backend maps the guest by domid through vhost-xen
        and never uses those addresses, and DomA's three vhost users
        rule out avoiding it from the config.
  0120  xen: do not silently drop IOREQ MMIO range (un)registration --
        meta-xt-driver-domain's 7.0.0-only 0110, rebased onto
        xen_native.h. qemu discarded the DMOP return codes, and a
        del/add pair that is not range-for-range symmetric leaves a
        4 KiB hole in Xen's merged ioreq rangeset: DomA panicked in
        virtio_pci with ESR 0x96000000 twelve times across
        2026-09-10..12 on RPi4. Venus multiplies the memory-topology
        commits and with them the churn. The patch checks the rc, logs
        it, and on -EEXIST unmaps the exact span and maps it again as
        one range.
  0121  virtio-gpu/xen: pin memfd-backed blobs (the ring, the reply
        shmem, the pools) through udmabuf before sharing them. mlock()
        keeps pages resident, not in place, and DomD migrates them: the
        render server read an all-zero command chunk where the guest
        had written one, and SurfaceFlinger kept dying. With
        vm.compact_unevictable_allowed=0 and
        vm.compaction_proactiveness=0 on DomD it stopped (RPi4,
        2026-09-12), which tied it to page migration. Without
        /dev/udmabuf or a sealable memfd the share is refused, so the
        guest gets VK_ERROR_MEMORY_MAP_FAILED rather than a ring that
        corrupts later.

meta-xt-driver-domain's qemu_%.bbappend applies to both qemu recipes, so
its six 7.0.0-only patches are now gated on PV.startswith('7.').
bb.utils.contains('PV', '7.0.0') would match only the whole token and
drop all six silently the day PV became 7.0.0+git<sha>; two of them are
what make 7.0.0 compile at all, so the symptom would not look like a
missing patch. Their status against 10.0.2 is recorded per patch: 0110
and 0111 are rebased as 0120 and 0118, 0112 is moot (no
hw/arm/xen_arm.c and no GUEST_TPM_BASE), 0113 is fixed in 10.0.2
itself, and 0101/0103 guard a pre-main-loop death that did not reproduce
on any boot of the RPi4 board verification (2026-09-10..12). The gtk+
and pixman PACKAGECONFIGs come back for the venus lane only, as the
configuration verified on hardware; whether 0117 makes them unnecessary
is left open.

virglrenderer: exporting guest resources, and Venus fixes

Every patch here is gated on venus, so --gpu=gl gets oe-core's
virglrenderer.

  0002  initialise the global gbm only when VIRGL_EXTERNAL_GBM is set.
        A non-NULL gbm is what makes a VIRGL_BIND_SHARED guest resource
        exportable as a dma-buf, which an Android guest compositing
        with Vulkan needs (without it vkGetMemoryResourcePropertiesMESA
        fails and Venus aborts in vn_relax), and it is what costs a GL
        guest half its frame rate, because GBM allocation on V3D is
        linear: 60.0 -> 29.0 fps on the AGL cluster. The device models
        are separate processes, so DomA sets the variable and DomU does
        not.
  0009  upstream 1fbd03b2 (MR 1561): 1.2.0's fallback minigbm flags
        collide with mesa's gbm.h, so every SAMPLER_VIEW resource asked
        mesa for a protected buffer. 0018 relies on it.
  0016  read a Venus object's type under the mutex that guards its
        destroy. Found while chasing "object 122 has type 19, not 9" on
        RPi4; not that failure's cause, but wrong on its own terms.
  0017  answer VK_ERROR_INVALID_EXTERNAL_HANDLE, not a fatal stream
        error, to a properties query for a resource that cannot be
        exported: with HWUI on Venus, system_server died every few
        minutes (RPi4, 2026-09-12). It also logs why a resource got no
        GBM backing.
  0018  the cause 0017 logged: a SHARED | SAMPLER_VIEW buffer (bind
        0x100008, an HWUI hardware bitmap) converted to gbm usage 0 and
        got no bo, so it could never be exported. Give it a linear one.
  0021  VKR_DEVICE_HEAP_MIB forces the device-local heap size vkr
        advertises. v3dv reports a share of DomD's RAM (645 MiB on a
        1408 MiB DomD), the guest's Skia/VMA takes heap/8 as its block
        size for any heap of 1 GiB or less, and every block is a fully
        populated v3d BO in DomD: HWUI took such blocks by the handful
        (96 MiB each on a 1664 MiB DomD) and DomD fell into a reclaim
        livelock. Clamping to 512 MiB still gave 64 MiB blocks and
        livelocked again; above 1 GiB VMA uses the 4 MiB blocks Skia
        asks for. Inert when unset.

Upstream's tiled-GBM allocation (MRs 1561/1644/1654) is not carried: it
corrupts a Venus-compositing guest's display, because the guest imports
its gralloc buffers as LINEAR while the host allocates them UIF. The
bbappend records the measurements and what reviving it needs.

mesa 26.2.2 in DomD, in both lanes

v3dv in poky's 26.0.5 submits a real, serialised control-list job for
every vkQueueSubmit that signals a semaphore: the AGL cluster on Venus
issues one render pass per frame and the host ran 11.1 bin jobs per
frame. mesa MR !42407 replaces those jobs with CPU-side syncobj merging;
it first ships in 26.2.0 and does not apply to 26.0.5, so DomD's mesa is
pinned to 26.2.2, with two of poky's patches dropped (one merged
upstream, one for a driver this target does not build). The pin is not
gated: both lanes run weston on the same V3DV and the fix is a v3dv one,
so --gpu=gl is the pre-Venus device model but not the pre-Venus mesa.
Drop the pin when poky's mesa reaches 26.2.0.

DomD: the kernel's dma-buf frame numbers, and the Vulkan runtime

Mesa's venus backs its large mappable allocations with dma-bufs, and a
dma-buf mapping is VM_PFNMAP, so /proc/self/pagemap reports nothing for
it. The DomD kernel's 0014 adds IOCTL_GNTDEV_DMABUF_IMP_TO_GFNS, which
returns the frame-number array gntdev-dmabuf already builds on its
import path; the import stays registered, so the pages stay in place
until it is released. venus-gntdev-dmabuf.cfg enables
XEN_GRANT_DMA_ALLOC and XEN_GNTDEV_DMABUF, which both boards' defconfigs
leave unset. Numbered 0014 because 0013 is the brcmstb-l2 fix, and gated
on venus.

The DomD image installs mesa-vulkan-drivers, vulkan-loader and
vulkan-tools under the same gate. The first two already arrive through
weston's Vulkan renderer -- the loader as a dependency of it, the ICD
only as the loader's RRECOMMENDS -- so a weston built without that
renderer, or BAD_RECOMMENDATIONS, could drop them silently, and Venus
cannot work without the ICD; vulkan-tools (vulkaninfo) is the one new
package.

DomA and DomU configs

Both guest configs carry XT_VENUS_GPU_OPTS_PLACEHOLDER on their
virtio-gpu-gl-pci line. do_install replaces it with the yaml's
XT_VENUS_GPU_OPTS: ",hostmem=256M,blob=true,venus=true" for GPU=vulkan,
and the empty string for --gpu=gl, which leaves the line as it was.
doma.cfg also carries XT_VENUS_QEMU_ENV_PLACEHOLDER in qemu_envs, which
the vulkan lane replaces with VIRGL_EXTERNAL_GBM=1,
V3DV_MAX_BO_CACHE_SIZE=8 and VKR_DEVICE_HEAP_MIB=1088 and the gl lane
deletes. The cache size bounds the freed GEM BOs each render server
keeps: nine Venus render servers held ~0.5 GiB of DomD that way. The
heap size is 0021's knob; with both, the cold-start and
screen-transition stresses that stalled DomD pass with DomD MemAvailable
never below ~460 MiB and no guest allocation of 64 MiB or more (RPi4
4 GiB SKU). A token left in either file is a bbfatal, because qemu exits
on an unknown -device property, and every substituted value is in
do_install[vardeps]. Outside moulin XT_VENUS_GPU_OPTS defaults to empty,
since venus=true on a qemu without the property is a config qemu
rejects.

qemu 10 also exits on two 7.0.0-xt-only options -- the virtio-snd-pci
device name and virtio-blk-pci's scsi= property, both measured on
RPi5. domu.cfg carries both; doma.cfg carries scsi= and gains
virtio-snd in the bt-a group, so until then the rename finds nothing
there. When XT_DM_QEMU_VERSION, taken from PREFERRED_VERSION_qemu, is
not 7.x, do_install renames the sound device to virtio-sound-pci,
drops scsi=off and the `-vga std` qemu 10 only warns about, and fails
the build if any of them is left.

DomA's AOSP tree also gets, whatever the lane,
aosp-patches/vendor/epam/mesa3d_upstream/0001: report protectedMemory
off in the guest Venus ICD. Venus forwards whatever the host driver
reports, and SkiaVkRenderEngine's blur preallocates protected buffers
when the device advertises the feature, which put SurfaceFlinger in a
restart loop on an Intel-hosted run. V3DV reports false itself, so on
either Raspberry Pi this is defensive.

build.sh: GPU, with Vulkan as the default

--gpu=vulkan|gl (GPU, default vulkan) and --devel (ENABLE_DEVEL, default
no) are validated and passed to moulin and rouge. --gpu=gl prints a
NOTE on what the pre-Venus stack is, and that DomA's AOSP-side
settings come from this tree whatever --gpu says, so a DomA built here
still asks for Vulkan compositing. The SD image name carries -Venus or
-GL.

The AGL guest is built from the AGL manifest on poky scarthgap, whose
DISTRO_FEATURES have no vulkan and whose mesa never builds the virtio
Vulkan driver. For GPU=vulkan build.sh writes four conf lines -- the
vulkan feature, the virtio driver, the Vulkan runtime and the Vulkan
cluster embedder -- to .agl-venus.conf, hands the file to the container,
and replaces a previous marker-delimited block in conf/local.conf rather
than appending another. meta-agl-venus is added to the AGL build and
removed again for --gpu=gl, because bitbake-layers only ever adds.
README gains the --gpu and --devel rows, and .gitignore the conf file.

README's cockpit diagram and its software-versions table give DomD's
mesa as 26.2.2 and its device model as qemu 10.0.2-xt, 7.0.0-xt with
--gpu=gl; its Xen row counts the shared series at 32 patches, 4.22-0007
and 4.22-0008 among the ones authored here; and its repository layout
lists meta-agl-venus, the qemu 10.0.2 recipe meta-xt-qemu now holds, and
tools/check-rpi4-memory-map.py, which the rpi4 commit of this group
adds. docs/DESIGN.md's Wrynose port notes give the mesa pin too, in
place of the stock 26.0.5 they described.

meta-agl-venus: Venus on the AGL guest

A layer for the AGL build only (LAYERSERIES_COMPAT scarthgap,
LAYERDEPENDS core flutter-layer agldemo). Scarthgap's mesa 24.0.7, once
the conf lines have it build the Venus ICD, cannot use it here:

  mesa 0001  upstream 087e9a96 (MR 29040): make cross-device optional.
             qemu does not advertise VIRTIO_GPU_F_RESOURCE_UUID, so
             vkCreateInstance failed ("required kernel param 5 is
             missing").
  mesa 0002  do not suballocate device memory. Every buffer bound to a
             sub-range of the 16 MiB pool landed at the pool base on
             the host; measured in DomU, a fill aimed at one buffer
             landed in another and vkWaitForFences never returned.
  mesa 0003  let virgl enumerate dma-buf format modifiers, a proof of
             concept. With none, weston-simple-dmabuf-feedback listed
             all 34 formats as NONE_INVALID, Venus forced LINEAR
             scanout images and the host re-tiled them every frame
             (2122 shadow updates in 40 s under V3D_DEBUG=perf).

0001 and 0002 are 24.0.7-only; 0003's defect is still in 26.x, so an
uprev has to rebase it rather than drop it. The wildcard bbappend makes
a newer mesa fail do_patch rather than drop any of them silently.

For the cluster, flutter-auto-vulkan is a second embedder built with the
Vulkan backend, which ivi-homescreen selects at compile time, with a
patch to build against scarthgap's Vulkan-Headers.
flutter-cluster-dashboard-conf-vulkan is a systemd drop-in that points
the service at it with --enable-impeller, in its own package, which
only the Vulkan lane installs. flutter-engine 0001 trims Impeller's
thread-local pool caches in RenderToTarget, whose leak grew the host
renderer with no plateau; upstream fixed the same leak in
flutter/flutter#182265, in GPUSurfaceVulkanImpeller::AcquireFrame,
which engine 3.32.5 predates. flutter-engine 0002 drops the onscreen
swapchain from 4x MSAA to 1x, a product decision taken on measurement,
and in the Vulkan lane flutter-auto, the OpenGL embedder installed
alongside, drops egl-multisample to match; --gpu=gl keeps meta-flutter's
4x. Measured on the RPi5 DomU at 1080x1920: 54.0 fps once the host
could import the guest's dma-bufs (qemu 0117) and 60.0 with explicit
modifiers (mesa 0003), against 60.0 for the Skia/OpenGL lane.

meta-rpi-sodev-devel: the gate, the reproducers and the diagnostics

The opt-in layer ENABLE_DEVEL=yes adds to the DomD build; none of this
belongs in a shipping image.

  xt-venus-check  sodev-venus-gate.sh, the phase 0-3 gate, ordered so
        a failure names the layer it is in: a baseline, the host V3DV
        requirements (VK_EXT_image_drm_format_modifier, /dev/udmabuf),
        whether this qemu's virtio-gpu-gl has a venus property, and
        native Vulkan drawing against the running compositor. Exit 0
        PASS, 1 FAIL, 2 INCONCLUSIVE.
  xt-venus-diag  vk-fence-test, vk-gl-import-test and
        vk-suballoc-probe, headless reproducers for the two guest-side
        defects this lane fixed (meta-agl-venus' mesa 0002 and qemu
        0117), kept as regression detectors: exit 1 for a setup
        failure, 2 when a defect reproduces, 0 for a clean run.
  virglrenderer 0015, 0019  a command-stream dump with a live sanity
        assert, and a log line per guest vkAllocateMemory of 64 MiB or
        more; with VKR_DEVICE_HEAP_MIB=1088 the expected reading is
        zero such lines. Gated on venus and applied after the product
        series.
  Xen 4.22-0009  the guest-abort injection prints move from gdprintk,
        compiled out of a release build, to gprintk, and two more are
        added, so a guest dying on ESR 0x96000000 names its path in xl
        dmesg. A product hypervisor is a release build, which is why
        this lives here. It is not the toolstack's 4.22-0009; the two
        series are numbered independently.

The DomD image bbappend becomes rpi5-image-xt-domd-%.bbappend: both
boards build rpi5-image-xt-domd-v4h, which only requires the -vc4
recipe, so a -vc4 bbappend never reached the shipped image. It appends
to DEBUG_PACKAGES rather than assigning it, so the base recipe's own
list (htop and strace among it) is kept. The in-tree DomU debug image
gets the guest Vulkan runtime and the reproducers under the venus gate.

Documentation

docs/VULKAN-VENUS.md records the lane: why Venus is the only candidate,
what GPU=vulkan turns on and why the main pieces are needed (the
recipes and patch headers carry the reasons for the rest), the phased
verification procedure with the numbers to expect, the defects that had
to be root-caused, the AGL cluster measurements and the Raspberry Pi 4
board run of 2026-09-12. It is written as a record of what was
measured, and it keeps the explanations that were eliminated so that
they are not re-walked. README, BUILD, DESIGN and TROUBLESHOOTING link
it from their documentation map. DESIGN's paragraph on patch trailers
is corrected on the way: it said the kernel patches spell the agent
ClaudeCode and pass checkpatch.pl --strict clean, while every patch
here that carries the trailer, the kernel ones included, spells it
Claude Code, which checkpatch reports as BAD_SIGN_OFF. The paragraph
also says that not every patch carries it: among those that do not are
the xen-troops fork series and third-party backports such as Zephyr's
0022-0024 and the qemu 7.0 0113.

tools/yaml-drift-baseline.txt changes twice, for two lines the rpi4
commit of this group brings to rpi4-sodev.yaml. It records the BOARD_RAM
description that commit writes for the 4g SKU (DomD 1408 MiB with
GPU=vulkan, 1024 with gl), in place of the line it replaces. And it no
longer records rpi5-sodev.yaml's `- [BOARD_RAM, "%{BOARD_RAM}"]` in the
linux flavour's dom0 conf as a difference, because that commit gives
rpi4-sodev.yaml the same line: the rpi4 DomA's size follows BOARD_RAM
there as well. Until that commit tools/check-yaml-drift.py, and
tools/check-domz.sh through it, report both together: two unrecorded
differences -- the description still in rpi4-sodev.yaml and the dom0
line -- and one stale baseline entry, the recorded description (78
functional differences against a baseline of 77).

This commit alone does not build: build.sh passes --GPU and
--ENABLE_DEVEL, which moulin rejects until the rpi4 and rpi5 commits of
this group declare them in their yamls.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Yuichi Kusakabe <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

engine flutter/engine related. See also e: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants