Repository navigation
Description
Summary
Since 3.44, DriverInfoVK::IsKnownBadDriver() sends Adreno ≤ 650 to OpenGL ES (the rule cites #178285 and #178498). That check only runs after GetActualRenderingAPIForImpeller has created a complete AndroidContextVKImpeller, so every one of these devices pays for Vulkan setup on each cold start and then throws it away. The GLES backend it falls back to then builds its pipelines in ContentContext's constructor, also on the raster thread and also before the first frame.
On a Snapdragon 678 / Adreno 612 phone that is ~150 ms of raster-thread CPU on the cold-start critical path. It didn't exist on 3.35.7, where these GPUs stayed on Vulkan.
The ordering is unchanged on master today: the emulator, Huawei, MediaTek and IsKnownBadSOC checks return early, and the Adreno rule is still only reached through the ContextVK that gets built right after them.
Environment
- Flutter 3.44.9 stable (framework 6b182d2, engine 5a2a6a4), release AOT build (
profileablefor measurement) - Redmi Note 10 (M2101K7AI), Snapdragon 678, Adreno 612, 4 GB RAM, Android 15 (AOSP build),
ro.product.board=sm6150
Evidence
logcat on one cold start (both lines from the same process, 18 ms apart):
15:13:09.699 I flutter : [IMPORTANT:flutter/shell/platform/android/android_context_vk_impeller.cc(62)] Using the Impeller rendering backend (Vulkan).
15:13:09.717 I flutter : [IMPORTANT:flutter/shell/platform/android/android_context_gl_impeller.cc(104)] Using the Impeller rendering backend (OpenGLES).
simpleperf (cpu-clock, dwarf call graphs, unstripped libflutter.so), raster thread, launch → first frame:
| Phase | Raster CPU | Top frames |
|---|---|---|
| Vulkan probe | ~44 ms (of 62 ms in SetupImpellerContext) |
AndroidContextDynamicImpeller::SetupImpellerContext → AndroidContextVKImpeller::AndroidContextVKImpeller → impeller::ContextVK::Setup → vulkan::api::CreateInstance → vulkan.adreno.so |
| GLES pipeline pre-build | ~91 ms | PlatformViewAndroid::CreateRenderingSurface → AndroidSurfaceGLImpeller::CreateGPUSurface → AiksContext → impeller::ContentContext::ContentContext → GenericRenderPipelineHandle → PipelineLibraryGLES::GetPipeline |
Also on the critical window, on a worker: FlutterJNI.prefetchDefaultFontManager → SkFontMgr_Android::addFamily, ~118 ms CPU.
Cold start, am start -W TotalTime, 15 runs each, same device, medians:
| Build | Impeller (GLES after probe) | Skia (--enable-impeller=false) |
|---|---|---|
| A | 877 ms | 770 ms |
| B | 838 ms | 761 ms |
Field data for our app: Play Vitals "slow cold start" went from 4.71% on the release built with 3.35.7 to 8.44% on the next release (3.44.9), concentrated on 3–4 GB devices on Android 10/11. That release also added one analytics SDK, but profiling puts its CPU after the first frame, so we attribute the jump mainly to the engine. It isn't all Adreno: the same tier includes MediaTek phones, which this report doesn't cover.
Why it's new in 3.44
In 3.35.7, IsKnownBadDriver() has no Adreno rule (only Huawei, Samsung Xclipse, PowerVR < CXT), so Adreno 6xx ran Impeller Vulkan, where pipelines aren't built synchronously on the raster thread. In 3.44.9 the Adreno ≤ 650 rule exists, but it's evaluated inside the "create a Vulkan context and check IsValid()" step of GetActualRenderingAPIForImpeller (android_context_dynamic_impeller.cc).
Ask
Decide Adreno ≤ 650 before building the ContextVK: e.g. from vkGetPhysicalDeviceProperties alone, or by caching the decision per build fingerprint, the way the emulator / Huawei / MediaTek / IsKnownBadSOC checks already short-circuit ahead of it.
Related
- The GLES pipeline half is already being worked on: [Impeller] Allow coarse prioritization of PSO preflight tasks. #176665 (PSO prioritisation) and [Impeller]Use the IO context for OpenGL program setup #185723 (GLES program setup on the IO thread, fixes [Impeller] [OpenGL] Use the IO context for OpenGL program setup. #176657). [Impeller]Use the IO context for OpenGL program setup #185723 is on
masterbut not in 3.47.x, and we haven't measured it. The probe cost above is separate and remains either way. - Android slow cold start & slow warm start caused by Impeller #175577 and Why does Flutter cold start take significantly longer on Impeller/OpenGL ES than Impeller/Vulkan? #190618 report slower Android cold start on Impeller/GLES in general. This issue is the specific extra cost on GPUs that 3.44 moved from Vulkan to GLES.
- [Android] ImpellerBackend / --impeller-backend is ignored in release builds #192467:
ImpellerBackendis ignored in release builds, so apps can't skip the probe themselves.
Perfetto isn't available on this device (no tracefs). The simpleperf recording and symbolized report are available on request.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
mbcorona commentedon Sep 29, 2026
Hi @KrishnaRupeezy, thanks for the report and the regression analysis.
Routing to the engine team for further investigation.
Avoid most vulkan initialization for known bad vulkan drivers (flutte…
github-actions commentedon Oct 22, 2026
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.Avoid most vulkan initialization for known bad vulkan drivers (flutte…