Skip to content

Avoid most vulkan initialization for known bad vulkan drivers - #193875

Merged
auto-submit[bot] merged 4 commits into
flutter:masterfrom
walley892:vulkan-init
Oct 8, 2026
Merged

auto-submit[bot] merged 4 commits into
flutter:masterfrom
walley892:vulkan-init

Conversation

@walley892

Copy link
Copy Markdown
Contributor

Adds a short-circuit in vulkan initialization for known bad devices (e.g., IsKnownBadDriver()==True).

Adds a callback should_reject_device to the Vulkan context initialization to allow callers to specify a fast fail during context creation before the bulk of the Vulkan context creation operations are kicked off. This is only used on Android at the moment.

Fixes #193502

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant in-code documentation (doc comments with ///).
  • If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@github-actions github-actions Bot added platform-android Android applications specifically engine flutter/engine related. See also e: labels. e: impeller Impeller rendering backend issues and features requests team-android Owned by Android platform team labels Oct 6, 2026
@walley892 walley892 added the CICD Run CI/CD label Oct 6, 2026
@walley892
walley892 marked this pull request as ready for review October 6, 2026 00:26
@walley892
walley892 requested a review from a team as a code owner October 6, 2026 00:26
@walley892
walley892 requested review from camsim99 and gaaclarke and removed request for a team October 6, 2026 00:26

@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 introduces an optional should_reject_device policy hook in ContextVK::Settings to allow early rejection of Vulkan physical devices (such as known bad drivers on Android) before performing expensive setup operations. It also defers the initialization of worker threads and the pipeline library. Feedback was provided on a unit test where std::string_view::copy is used without explicit null-termination, which could leave trailing garbage characters in the device name buffer.

@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.

Looking good, let's just refactor to avoid the indirection.

Comment on lines +95 to +100
/// An optional policy hook consulted as soon as a physical device has been
/// selected, before the logical device, allocator, pipeline cache, shader
/// modules, or worker threads are created. Returning true aborts setup and
/// leaves the context invalid.
std::function<bool(const DriverInfoVK&)> should_reject_device;

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.

Instead of making this a callback, let's split up ContextVK::Setup. Then we'll have a method to do the work up until the point where we have the DriverInfoVK. That method is already super big already.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Aye aye, captain. Added a method SelectDevice() that returns an object which the caller can use to reject the device or call CreateContext() on to finish initialization.

@walley892
walley892 requested a review from gaaclarke October 6, 2026 16:59
gaaclarke
gaaclarke previously approved these changes Oct 6, 2026
/// Initialize the Vulkan instance and select a physical device, returning its
/// `DriverInfoVK` so the caller can inspect or reject the device before the
/// remainder of context setup runs.
static std::optional<DeviceSelection> SelectDevice(Settings settings);

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.

nit: this should be absl::StatusOr<DeviceSelection>

@walley892
walley892 requested review from gaaclarke and removed request for camsim99 October 6, 2026 23:00

@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.

lgtm, thanks @walley892

@walley892 walley892 added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 7, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Oct 8, 2026
Merged via the queue into flutter:master with commit af028a8 Oct 8, 2026
23 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Oct 8, 2026
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
…r#193875)

Adds a short-circuit in vulkan initialization for known bad devices
(e.g., IsKnownBadDriver()==True).

Adds a callback `should_reject_device` to the Vulkan context
initialization to allow callers to specify a fast fail during context
creation before the bulk of the Vulkan context creation operations are
kicked off. This is only used on Android at the moment.

Fixes flutter#193502 

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant in-code documentation (doc comments with
`///`).
- [x] If this PR introduces a new feature or capability, I created and
linked a website documentation issue or PR in [flutter/website] (or
verified none is needed).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
opensource-fork-sync Bot pushed a commit to cla7aye15I4nd/opensource-flutter__flutter that referenced this pull request Nov 2, 2026
Impeller's Android autoselect falls back to OpenGLES for several
reasons. Some were silent: emulators, Huawei devices, and MediaTek
vendor SDKs below 32. Known bad SoCs and known bad Vulkan drivers were
logged only at INFO, which is hidden by default, with the same text for
both. A profile or release log therefore shows only `Using the Impeller
rendering backend (OpenGLES).`, and app developers and triagers cannot
tell why Vulkan was not used.

This PR logs every fallback branch at `FML_LOG(INFO)`, visible with
`--verbose-system-logs`, one line each and with the values that
triggered it. All lines are in `GetActualRenderingAPIForImpeller`
(`android_context_dynamic_impeller.cc`) unless noted:

| branch | message |
|---|---|
| emulator | `Emulator detected, falling back to OpenGLES.` |
| Huawei | `Huawei device detected
(ro.com.google.clientidbase=android-huawei), falling back to OpenGLES.`
|
| MediaTek vendor SDK | `MediaTek vendor API level <n> is below 32
(ro.vendor.mediatek.platform=<value>), falling back to OpenGLES.` |
| known bad SoC | `Known bad SoC encountered (ro.product.board=<board>),
falling back to OpenGLES.` |
| Vulkan probe invalid | `Could not create a Vulkan context, falling
back to OpenGLES.` |

In `android_context_vk_impeller.cc` (`CreateImpellerContext`), the
failing step is logged just before the probe line:

| step | message |
|---|---|
| device selection | `Could not select a Vulkan device: <absl status
message>` |
| known bad driver | `Known bad Vulkan driver encountered.` followed by
`DriverInfoVK::DumpToLog()` (name, API version, driver version, vendor,
device type) |
| context setup | `Could not set up the Vulkan context on the selected
device.` |

The vk messages do not say "falling back", because forced Vulkan
(`ImpellerBackend=vulkan`) uses the same function and aborts instead.
The `Using the Impeller rendering backend (Vulkan)` banner keeps the
structure from flutter#193875: it only prints for a non-null context.

No new log line contains the phrase "Using the Impeller rendering
backend". devicelab `hello_world_impeller.dart` counts logcat lines with
that phrase, so its backend count is unchanged.

### Observed on device

moto g54 5G (MediaTek MT6855, PowerVR BXM-8-256, Android 15, Vulkan
driver 1.15@6133110), profile build of master plus this PR, default
backend selection, `--verbose-system-logs`, logcat from process start:

```
I flutter : [INFO:flutter/shell/platform/android/android_context_dynamic_impeller.cc(116)] MediaTek vendor API level 31 is below 32 (ro.vendor.mediatek.platform=MT6855), falling back to OpenGLES.
I flutter : [IMPORTANT:flutter/shell/platform/android/android_context_gl_impeller.cc(105)] Using the Impeller rendering backend (OpenGLES).
```

Before this PR, only the second line was printed. With Vulkan forced
(and the PowerVR denylist disabled locally for the experiment), no
fallback line appears and the only Impeller line is the `(Vulkan)`
banner.

Only the MediaTek branch fired on hardware. The emulator, Huawei, bad
SoC and bad driver branches and the three Vulkan setup-failure steps
were not exercised on a device; each is a log-only addition next to an
existing `return nullptr`.

### Tests

None added. The change is log-only and the tree has no tests asserting
these messages: `shell/` has no other matches for "Known bad Vulkan" or
"falling back", and `android_context_dynamic_impeller_unittests.cc` has
no log checks. I'd like to request a test exemption, since behavior is
unchanged beyond logging.

### Related issues

- flutter#192467: the engine ignores `ImpellerBackend` in release builds, and
the maintainer answer asked for device properties in order to denylist.
With this PR, the fallback reason and the triggering property values are
in the default log.
- flutter#193502 (fixed by flutter#193875): skip full Vulkan setup on denylisted
drivers. This PR adds the reason line on that early-reject path, and on
the device-selection and context-setup failures.
- flutter#193148: the MediaTek vendor-SDK gate from flutter#186405. A build with this
PR is how the gate was confirmed as the cause on a second device:
flutter#193148 (comment)

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant in-code documentation (doc comments with
`///`).
- [x] If this PR introduces a new feature or capability, I created and
linked a website documentation issue or PR in [flutter/website] (or
verified none is needed).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/CONTRIBUTING.ai.md
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[flutter/website]: https://github.com/flutter/website
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
gmackall pushed a commit to gmackall/flutter that referenced this pull request Nov 3, 2026
Impeller's Android autoselect falls back to OpenGLES for several
reasons. Some were silent: emulators, Huawei devices, and MediaTek
vendor SDKs below 32. Known bad SoCs and known bad Vulkan drivers were
logged only at INFO, which is hidden by default, with the same text for
both. A profile or release log therefore shows only `Using the Impeller
rendering backend (OpenGLES).`, and app developers and triagers cannot
tell why Vulkan was not used.

This PR logs every fallback branch at `FML_LOG(INFO)`, visible with
`--verbose-system-logs`, one line each and with the values that
triggered it. All lines are in `GetActualRenderingAPIForImpeller`
(`android_context_dynamic_impeller.cc`) unless noted:

| branch | message |
|---|---|
| emulator | `Emulator detected, falling back to OpenGLES.` |
| Huawei | `Huawei device detected
(ro.com.google.clientidbase=android-huawei), falling back to OpenGLES.`
|
| MediaTek vendor SDK | `MediaTek vendor API level <n> is below 32
(ro.vendor.mediatek.platform=<value>), falling back to OpenGLES.` |
| known bad SoC | `Known bad SoC encountered (ro.product.board=<board>),
falling back to OpenGLES.` |
| Vulkan probe invalid | `Could not create a Vulkan context, falling
back to OpenGLES.` |

In `android_context_vk_impeller.cc` (`CreateImpellerContext`), the
failing step is logged just before the probe line:

| step | message |
|---|---|
| device selection | `Could not select a Vulkan device: <absl status
message>` |
| known bad driver | `Known bad Vulkan driver encountered.` followed by
`DriverInfoVK::DumpToLog()` (name, API version, driver version, vendor,
device type) |
| context setup | `Could not set up the Vulkan context on the selected
device.` |

The vk messages do not say "falling back", because forced Vulkan
(`ImpellerBackend=vulkan`) uses the same function and aborts instead.
The `Using the Impeller rendering backend (Vulkan)` banner keeps the
structure from flutter#193875: it only prints for a non-null context.

No new log line contains the phrase "Using the Impeller rendering
backend". devicelab `hello_world_impeller.dart` counts logcat lines with
that phrase, so its backend count is unchanged.

### Observed on device

moto g54 5G (MediaTek MT6855, PowerVR BXM-8-256, Android 15, Vulkan
driver 1.15@6133110), profile build of master plus this PR, default
backend selection, `--verbose-system-logs`, logcat from process start:

```
I flutter : [INFO:flutter/shell/platform/android/android_context_dynamic_impeller.cc(116)] MediaTek vendor API level 31 is below 32 (ro.vendor.mediatek.platform=MT6855), falling back to OpenGLES.
I flutter : [IMPORTANT:flutter/shell/platform/android/android_context_gl_impeller.cc(105)] Using the Impeller rendering backend (OpenGLES).
```

Before this PR, only the second line was printed. With Vulkan forced
(and the PowerVR denylist disabled locally for the experiment), no
fallback line appears and the only Impeller line is the `(Vulkan)`
banner.

Only the MediaTek branch fired on hardware. The emulator, Huawei, bad
SoC and bad driver branches and the three Vulkan setup-failure steps
were not exercised on a device; each is a log-only addition next to an
existing `return nullptr`.

### Tests

None added. The change is log-only and the tree has no tests asserting
these messages: `shell/` has no other matches for "Known bad Vulkan" or
"falling back", and `android_context_dynamic_impeller_unittests.cc` has
no log checks. I'd like to request a test exemption, since behavior is
unchanged beyond logging.

### Related issues

- flutter#192467: the engine ignores `ImpellerBackend` in release builds, and
the maintainer answer asked for device properties in order to denylist.
With this PR, the fallback reason and the triggering property values are
in the default log.
- flutter#193502 (fixed by flutter#193875): skip full Vulkan setup on denylisted
drivers. This PR adds the reason line on that early-reject path, and on
the device-selection and context-setup failures.
- flutter#193148: the MediaTek vendor-SDK gate from flutter#186405. A build with this
PR is how the gate was confirmed as the cause on a second device:
flutter#193148 (comment)

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant in-code documentation (doc comments with
`///`).
- [x] If this PR introduces a new feature or capability, I created and
linked a website documentation issue or PR in [flutter/website] (or
verified none is needed).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/CONTRIBUTING.ai.md
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[flutter/website]: https://github.com/flutter/website
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD e: impeller Impeller rendering backend issues and features requests engine flutter/engine related. See also e: labels. platform-android Android applications specifically team-android Owned by Android platform team

Projects

None yet

2 participants