Repository navigation
Description
Steps to reproduce
Not reproducible on demand — this is a recurring production ANR reported by Google Play Console (user-perceived ANR clusters) for a Flutter paint-by-number game. It fires when the app is sent to background: one dump is under Activity.performStop, the other under View.dispatchWindowVisibilityChanged — both reach FlutterSurfaceView → surfaceDestroyed.
Both occurrences are Android 16 (SDK 36) tablets with Adreno GPUs (Samsung Galaxy Tab A9+, Honor Pad X8a), rendering with Impeller on the OpenGLES backend (GPUSurfaceGLImpeller visible in the raster stack). Three Play Console clusters share this exact signature (8 users / 8 events in the last 28 days for v352 of the app).
Expected results
Backgrounding the app tears down the surface without blocking the Android main thread indefinitely.
Actual results
The main thread blocks in Shell::OnPlatformViewDestroyed waiting on fml::AutoResetWaitableEvent, while the raster thread is mid-frame inside Surface::dequeueBuffer, waiting for a free buffer slot on a window that is being hidden — with Android 16's BLAST buffer queue that slot is never released, so neither thread ever makes progress → "Input dispatching timed out" ANR.
Main thread (identical in both dumps):
"main" tid=1 Native
#02 pc ... libc.so (pthread_cond_wait+76)
#03 pc ... libapp/libflutter (std::__fl::condition_variable::wait(std::__fl::unique_lock<std::__fl::mutex>&))
#04 pc ... (fml::AutoResetWaitableEvent::Wait())
#05 pc ... (flutter::Shell::OnPlatformViewDestroyed())
#06 pc ... (flutter::PlatformViewAndroid::NotifyDestroyed())
#07 pc ... (flutter::SurfaceDestroyed(_JNIEnv*, _jobject*, long))
at io.flutter.embedding.engine.FlutterJNI.onSurfaceDestroyed (FlutterJNI.java:669)
at io.flutter.embedding.engine.renderer.FlutterRenderer.stopRenderingToSurface (FlutterRenderer.java:1170)
at io.flutter.embedding.android.FlutterSurfaceView$1.surfaceDestroyed (FlutterSurfaceView.java:81)
-- dump A: at android.view.SurfaceView.onWindowVisibilityChanged / ViewRootImpl.performTraversals
-- dump B: at android.view.SurfaceView.setWindowStopped / android.app.Activity.performStop (Activity.java:9947)
Raster thread, dump A (Galaxy Tab A9+, Android 16):
"1.raster" tid=108 Native
#02 pc ... libc.so (pthread_cond_clockwait+180)
#03 pc ... libgui.so (android::BufferQueueProducer::waitForFreeSlotThenRelock const+840)
#04 pc ... libgui.so (android::BufferQueueProducer::dequeueBuffer+564)
#05 pc ... libgui.so (android::Surface::dequeueBuffer+436)
#06-#12 vendor Adreno EGL (eglSubDriverAndroid.so / libGLESv2_adreno.so)
#13 pc ... (impeller::RenderPassGLES::OnEncodeCommands ... $_0::operator())
#14 pc ... (impeller::ReactorGLES::React())
#15 pc ... (impeller::Canvas::EndReplay())
#16 pc ... (impeller::RenderToTarget(...))
#17 pc ... (flutter::GPUSurfaceGLImpeller::AcquireFrame(...)::$_1 ... operator())
#18 pc ... (flutter::SurfaceFrame::Submit())
#19 pc ... (flutter::Rasterizer::DrawToSurfacesUnsafe(...))
#23 pc ... (flutter::Shell::OnAnimatorDraw ...)
Raster thread, dump B (Honor Pad X8a, Android 16) — identical shape, with the SDK-36 BLAST queue visible:
"1.raster" tid=112 Native
#01 pc ... libgui.so (android::BBQBufferQueueProducer::waitForBufferRelease const+380)
#02 pc ... libgui.so (android::BufferQueueProducer::dequeueBuffer+1172)
#03 pc ... libgui.so (android::Surface::dequeueBuffer+1256)
#04-#07 vendor Adreno EGL
... (same impeller::RenderPassGLES / ReactorGLES / Rasterizer frames as dump A)
Engine BuildId in both dumps: 0d216f3f630e1105257f8a3f74e22c9b43c22a51.
Possibly the same family as #107351 and #170196, but this variant is specifically the destroy handshake racing a mid-frame dequeueBuffer on a hidden window, which Android 16's buffer accounting seems to make persistent rather than transient.
Happy to attach the full Play Console ANR thread dumps if useful.
Code sample
N/A — production ANR; app uses a standard FlutterActivity (FlutterSurfaceView), no platform views on the affected screens.
Flutter version
Flutter 3.41.9 (stable, via FVM); flutter build apk --release, Impeller default-enabled (GLES backend on the affected devices).
Activity
bariskodas commentedon Aug 5, 2026
Additional data point — a third production dump shows the same stall on the resize path (
Shell::OnPlatformViewSurfaceChangedhandshake), not just destroy:Main thread (Honor Pad X8a, Android 16 / SDK 36 — same device model and same Adreno EGL driver build as dump B above):
Raster thread — byte-for-byte the same state as the destroy dumps:
So any of the
AutoResetWaitableEventsurface handshakes (changed and destroyed) can deadlock against a raster thread that is mid-frame indequeueBufferon an SDK-36 BLAST queue.bariskodas commentedon Aug 5, 2026
Third independent production occurrence of the destroy-variant (Play Console, v3.5.2, Honor Pad X8a / Android 16 / Impeller GLES — same device model as the earlier dumps, 23 days ago). Both halves of the deadlock are again visible simultaneously in one dump:
Main is latched on the raster thread acknowledging surface teardown; raster is blocked dequeuing a buffer on the window being hidden, which is never released. Consistent recurrence on SDK 36 budget tablets with Impeller GLES.
saurabh-mirajkar commentedon Aug 6, 2026
@bariskodas Thanks for the detailed report. The stack traces are helpful, but the issue is still based on production ANR reports without a reproducible case.
This also appears related to #169585, which reports a similar production ANR.
Since you're currently using Flutter
3.41.9, could you first verify whether this still occurs on the latest stable3.44.8? If it does, please let us know whether the stack traces remain the same after upgrading.If you're able to identify a reproducible sample or reliable reproduction steps, that would make the issue actionable for the team to investigate.
github-actions commentedon Aug 27, 2026
Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now.
If you find this problem please file a new issue with the same description, what happens, logs and the output of 'flutter doctor -v'. All system setups can be slightly different so it's always better to open new issues and reference the related ones.
Thanks for your contribution.
github-actions commentedon Sep 10, 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.