Repository navigation
Description
Steps to reproduce
Up front, so nobody wastes time: this is a production field report, not a locally reproduced bug. I do not own the affected hardware and have not been able to reproduce it on any device I have. I am filing it because the corruption pattern is specific enough to point at a concrete code path, and because IsKnownBadDriver() has no Mali handling at all (details under Actual results).
What the affected user did:
- Launch the app on a wheatek WP36_A16_EEA (WP36),
Build.HARDWARE = mt8788, Android 13. The MT8788 ships an Arm Mali-G72 MP3. - Open a screen whose body is a native map rendered through an Android platform view.
- The platform view is hosted in Virtual Display mode —
PlatformViewsService.initAndroidViewvia theAndroidViewwidget — and the nativeMapViewinside it is configured to use aTextureViewrather than aSurfaceView. - Observe the platform view region.
Relevant configuration:
- Flutter 3.41.6, framework
db50e20168, engine425cfb54d0. - Impeller enabled (default). The app's
AndroidManifest.xmlsets noio.flutter.embedding.android.EnableImpellerand noio.flutter.embedding.android.ImpellerBackend, so the engine picks its own backend. - The rest of the Flutter UI on the same screen is ordinary widgets composited on top of the platform view.
Expected results
The platform view region displays the content the native view drew into it, correctly.
Actual results
The platform view region is filled with corrupt pixels. Every Flutter-drawn widget on the same screen — app bar, scale bar, icon buttons, a rounded label pill, the FAB, the bottom navigation bar — renders pixel-perfect. Only the platform view is destroyed.
The corruption is not random noise. Zoomed in 8x (second and third attachments) it is clearly periodic and sheared:
- A small motif repeats horizontally at a fixed period.
- Each successive scanline is offset by a constant amount, producing diagonal banding.
- One band is a perfectly regular dot grid at a fixed pitch.
That is the signature of a buffer being sampled with an incorrect row stride / tiling layout rather than corrupt source content. The pixels are present and structured, the layout is misinterpreted. Genuinely corrupt source imagery would still show recognisable structure aligned to its own boundaries, and a driver producing random garbage would not produce a constant per-row shear.
In Virtual Display mode the native view draws into a VirtualDisplay-backed SurfaceTexture, which the engine imports as an external texture for Impeller to sample. On the Vulkan backend that is the SurfaceTexture trampoline path. A stride/tiling mismatch when importing that buffer into a Vulkan image would produce exactly this artifact, and would leave normal Flutter rendering untouched, which matches what is observed.
Why I think this is worth a denylist look regardless
In engine/src/flutter/impeller/renderer/backend/vulkan/driver_info_vk.cc on master, the engine already parses and stores the Mali generation, including G72:
// line 76
const std::unordered_map<std::string_view, MaliGPU> kMaliVersions = {
...
{"G76", MaliGPU::kG76},
{"G72", MaliGPU::kG72},
{"G52", MaliGPU::kG52},
...// line 300-306
adreno_gpu_ = GetAdrenoVersion(driver_name_);
...
mali_gpu_ = GetMaliVersion(driver_name_);
...
powervr_gpu_ = GetPowerVRVersion(driver_name_);But IsKnownBadDriver() consults adreno_gpu_ and powervr_gpu_ and never consults mali_gpu_:
// line 398
if (adreno_gpu_ && *adreno_gpu_ <= AdrenoGPU::kAdreno650) {
return true;
}
...
// line 425
if (powervr_gpu_.has_value() && powervr_gpu_.value() < PowerVRGPU::kCXT) {
return true;
}
return false;The only other reference to mali_gpu_ in the file is the getter at line 432 (return mali_gpu_;). So MaliGPU is tracked but is not, today, an input to the Vulkan fallback decision, while Adreno, PowerVR, Huawei and Samsung Xclipse all are. A 2018 Bifrost part like G72 MP3 on a low-end MediaTek board is the kind of driver that has needed workarounds elsewhere.
Possibly related, all involving platform views or Mali drivers on Impeller:
- Android Platform Views pixelated when imported via SurfaceTexture trampoline on Vulkan backend. #159688 — Android platform views pixelated when imported via SurfaceTexture trampoline on the Vulkan backend
- [Impeller] [Android] Native views not rendering on some devices #153228 — [Impeller][Android] Native views not rendering on some devices (Mali/MediaTek)
- [Impeller] Support external (surface) textures in Vulkan #137639 — [Impeller] Support external (surface) textures in Vulkan
- Using Android SurfaceTexture and Flutter Texture Widget together with Impeller enabled may cause problems. #145077 — Android SurfaceTexture and Flutter Texture widget together with Impeller
- [Impeller] [Vulkan] Graphical artifacts while rendering images #137002 — [Impeller][Vulkan] Graphical artifacts while rendering images (Mali-G52,
e: impeller-naughty-driver)
Code sample
Code sample
I do not have a verified minimal reproduction, and I want to be explicit about that rather than attach something I have not seen fail. The failure is specific to hardware I do not own, so anything I write here is an untested guess at the shape of the repro. What follows is the configuration the production app uses, reduced. It has not been confirmed to reproduce on an MT8788 device.
The essential ingredients are: Impeller on the Vulkan backend, an Android platform view in Virtual Display hosting mode, and a native view inside it that draws continuously into a TextureView.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(const MaterialApp(home: Repro()));
class Repro extends StatelessWidget {
const Repro({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
// Virtual Display hosting mode: the AndroidView widget routes through
// PlatformViewsService.initAndroidView. The native side of
// 'repro/native_view' should inflate a TextureView that redraws
// continuously, e.g. an animating Canvas or a GL surface.
const AndroidView(
viewType: 'repro/native_view',
layoutDirection: TextDirection.ltr,
creationParams: <String, dynamic>{},
creationParamsCodec: StandardMessageCodec(),
),
// Flutter-drawn overlay. In the production failure this layer is
// pixel-perfect while the platform view underneath is garbage.
const Positioned(
bottom: 40,
left: 0,
right: 0,
child: Center(
child: Material(
color: Colors.black87,
child: Padding(
padding: EdgeInsets.all(12),
child: Text('OVERLAY', style: TextStyle(color: Colors.white)),
),
),
),
),
],
),
);
}
}Screenshots or Video
Logs
Logs
I do not have logcat from the affected device. The report reached me as a screenshot plus an application-level log that contains no engine, Impeller, Vulkan or platform-view lines.
Flutter Doctor output
Doctor output
[!] Flutter (Channel [user-branch], 3.41.6, on macOS 26.5.2 25F84 darwin-arm64, locale en-US) [475ms]
! Flutter version 3.41.6 on channel [user-branch] at /Users/REDACTED/flutter
Currently on an unknown channel. Run `flutter channel` to switch to an official channel.
If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/setup.
! Upstream repository unknown source is not a standard remote.
Set environment variable "FLUTTER_GIT_URL" to unknown source to dismiss this error.
• Framework revision db50e20168 (6 months ago), 2026-03-25 16:21:00 -0700
• Engine revision 425cfb54d0
• Dart version 3.11.4
• DevTools version 2.54.2
• Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-native-assets, omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration
[✓] Android toolchain - develop for Android devices (Android SDK version 37.0.0) [6.9s]
• Android SDK at /Users/REDACTED/Library/Android/sdk
• Emulator version 37.1.11.0 (build_id 15917651) (CL:N/A)
• Platform android-37.0, build-tools 37.0.0
• Java binary at: /Users/REDACTED/Library/Java/JavaVirtualMachines/jdk-21.0.12+8/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment Temurin-21.0.12+8 (build 21.0.12+8-LTS)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 26.6) [1,091ms]
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 17F113
• CocoaPods version 1.17.0
[✓] Chrome - develop for the web [3ms]
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Connected device (3 available) [6.3s]
• macOS (desktop) • macos • darwin-arm64 • macOS 26.5.2 25F84 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 152.0.7977.83
[✓] Network resources [583ms]
• All expected network resources are available.
! Doctor found issues in 1 category.


Activity
mbcorona commentedon Sep 15, 2026
Hi @DjordjeMancic97 , thanks for the detailed report.
Routing to the engine team.
gaaclarke commentedon Sep 21, 2026
I'm moving this over to team-android since it has to do with platform views. I think there is some red herrings in this issue related to Impeller's backend selection logic. It seems more possible to be a platform view issue. The OP does not have reproduction steps though.
jesswrd commentedon Sep 22, 2026
@gmackall from android triage: Can you take a look at this to confirm that it really is a platform view issue?