Repository navigation
[Impeller] Dispatch make-current lifecycle event only on success - #190655
Closed
FelixMittermeier wants to merge 1 commit into
Closed
FelixMittermeier wants to merge 1 commit into
FelixMittermeier wants to merge 1 commit into
Conversation
This was referenced Sep 2, 2026
Contributor
Author
|
Closing this in favor of #192158 Context: #190640 (comment) |
pull Bot
pushed a commit
to Mu-L/flutter
that referenced
this pull request
Sep 23, 2026
Addresses flutter#190640 ## Reproduction Public deterministic reproduction: [dfdgsdfg/mali-crash-app](https://github.com/dfdgsdfg/mali-crash-app). The workload and the historical matrix table are documented in the [README](https://github.com/dfdgsdfg/mali-crash-app#diagnostic-ab-matrix). ## Evidence Confirmed facts from the diagnostic engine and the same production-like scenario: - The shared renderer deletes a texture name. - The same numeric name is regenerated on the resource context. - The upload path ends with `isTexture=false` for that name. - The first isolated error is `FramebufferTexture2D`: `GL_INVALID_OPERATION`, followed by a missing framebuffer attachment. The [trace matrix 7268086803036215683](https://console.firebase.google.com/project/us-app-ea67d/testlab/histories/bh.d17e9c8f630d19e0/matrices/7268086803036215683), [force-rebind pass matrix 7248171571680282013](https://console.firebase.google.com/project/us-app-ea67d/testlab/histories/bh.d17e9c8f630d19e0/matrices/7248171571680282013), and [verify-3 matrix 9163761808229023214](https://console.firebase.google.com/project/us-app-ea67d/testlab/histories/bh.d17e9c8f630d19e0/matrices/9163761808229023214) are the key Test Lab runs. Inference: the trace and A/B results are consistent with a deleted object remaining bound and Mali treating a rebind to the same numeric name as no state transition. This is an inference about the driver behavior, not a claim that the GLES implementation violates the object-name specification. ## Change The direct GLES buffer-to-texture upload path now performs one extra zero bind immediately before binding the destination texture. The final binding state is unchanged. The RGBA unit test uses deterministic texture name `7` and preserves the ordered `0` then `7` binding sequence. This is a minimal workaround and does not supersede [flutter#190655](flutter#190655): that PR covers a different make-current failure path, while this reproduction had a successful/current resource context. flutter#190655 was not directly tested here. ## Physical validation Using a Flutter 3.44.8-based diagnostic engine with the same app, Scenario 9, and Mali device: - Four affected diagnostic runs crashed after approximately 7–10 seconds. - The force-rebind A/B passed 4/4 runs, each running for 606 seconds, with no `GL_INVALID_OPERATION`, FBO failure, `isTexture=false`, or fatal signal observations. The latest-master patch received the host validation below; the physical Test Lab binaries were built from the Flutter 3.44.8-based diagnostic engine, not from this latest-master patch. ## Host validation - `BlitCommandGLESTest.BlitCopyBufferToTextureCommandGLESRGBA`: 1/1 passed - `BlitCommandGLESTest.*`: 11/11 passed - `ProcTableGLES.*`: 5/5 passed - `ReactorGLES.*`: 6 passed, 1 skipped because the host does not support labelling - `ImageDecoderNoGLTest.*`: 6/6 passed - Host `impeller_unittests` and `ui_unittests` builds passed - clang-format and `git diff --check` passed ## Scope and trade-offs This is a narrow workaround validated for one deterministic reproduction; it is not an architectural redesign or a general fix for all GLES texture-binding paths. The current physical mechanism is inferred from the trace and A/B results; this does not prove that every Mali crash in flutter#190640 has the same cause. The workaround applies only to `BlitCopyBufferToTextureCommandGLES`; other GLES bind/upload paths remain unchanged. It adds one additional `glBindTexture` per direct buffer-to-texture upload. Affected callers include image decode, glyph atlas, small utility textures, and Flutter GPU buffer-to-texture overwrite/copy paths. The extra bind is likely small compared with texel transfer for normal uploads, but it has not been benchmarked; repeated small per-frame uploads may be sensitive. GL names come from the driver via `glGenTextures`, and Flutter cannot prevent numeric name reuse. Reactor-level name-reuse prevention is not a simple alternative: delayed deletion and `glFinish` add memory and stall cost, and do not directly force the observed same-name state transition. Reviewer guidance on performance and scope, including broader workaround plumbing if needed, is welcome.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #190640
When Android Impeller uses OpenGLES,
Context::MakeCurrentcurrently dispatcheskDidMakeCurrentto its lifecycle listeners even when the underlyingeglMakeCurrentcall fails.AndroidContextGLImpellerinterprets that event as permission to run GLES reactor work on the current thread, so queued image resize blits can execute without a current OpenGL context and reach the fatal incomplete-framebuffer check seen in the issue.The solution is to dispatch
kDidMakeCurrentonly aftereglMakeCurrentsucceeds while preserving the existing error logging and return value. This restores the lifecycle contract at the point where Impeller has the authoritative EGL result. A regression test uses EGL's cross-thread context ownership rule to make a secondMakeCurrentcall fail withEGL_BAD_ACCESSand verifies that only the successful bind emits the lifecycle event.Pre-launch Checklist
///).