Skip to content

[Impeller][Android] Adreno ≤ 650 builds a full Vulkan context on every cold start before falling back to OpenGL ES (~44 ms probe + ~91 ms GLES pipelines before first frame; regression 3.35 → 3.44) #193502

Closed

Description

@KrishnaRupeezy

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 (profileable for 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

Perfetto isn't available on this device (no tracefs). The simpleperf recording and symbolized report are available on request.

Activity

  1. added
    platform-androidAndroid applications specifically
    engineflutter/engine related. See also e: labels.
    in triagePresently being triaged by the triage team
    e: impellerImpeller rendering backend issues and features requests
    c: regressionIt was better in the past than it is now
    c: performanceRelates to speed or footprint issues (see "perf:" labels)
    on Sep 29, 2026
  2. mbcorona commented on Sep 29, 2026

    @mbcorona
    Member

    Hi @KrishnaRupeezy, thanks for the report and the regression analysis.
    Routing to the engine team for further investigation.

  3. added
    P2Important issues not at the top of the work list
    on Oct 5, 2026
  4. self-assigned this
    on Oct 6, 2026
  5. github-actions commented on Oct 22, 2026

    @github-actions

    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 -v and a minimal reproduction of the issue.

  6. locked as resolved and limited conversation to collaborators on Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work listc: performanceRelates to speed or footprint issues (see "perf:" labels)c: regressionIt was better in the past than it is nowe: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.found in release: 3.35Found to occur in 3.35found in release: 3.44Found to occur in 3.44in triagePresently being triaged by the triage teamplatform-androidAndroid applications specificallyteam-engineOwned by Engine team

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions