Skip to content

[web] Report skwasm WebGL context creation failure instead of hanging - #193293

Merged
auto-submit[bot] merged 8 commits into
flutter:masterfrom
kevmoo:issue-193223
Nov 11, 2026
Merged

auto-submit[bot] merged 8 commits into
flutter:masterfrom
kevmoo:issue-193223

Conversation

@kevmoo

@kevmoo kevmoo commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Note

Scope: This fixes the headless / GPU-flags variant of #193223, where skwasm cannot create a WebGL2 context and then hangs silently. The reporter later confirmed that their production symptom (platform view never attached, no errors) was caused by if (dart.library.js_util) conditional imports resolving to stubs under --wasm, and closed #193223. This PR turns the silent skwasm WebGL2 context failure uncovered by the issue's headless repro into a visible error. It does not make rendering work without WebGL2.

When skwasm fails to create a WebGL2 context on the worker (e.g. Chrome launched with --use-gl=angle --use-angle=gl --enable-gpu-rasterization --ignore-gpu-blocklist in some environments), Surface::ReceiveCanvasOnWorker printed Failed to create context! and returned without calling skwasm_reportInitialized. As a result:

  1. SkwasmSurface._initializedCompleter never completed.
  2. setSize / rasterizeToImageBitmaps awaited initialized forever, wedging the render loop (later scenes only overwrite renderQueue.next).
  3. Platform views injected during the synchronous measure pass of the first frame appeared, but any platform view mounted later (e.g. the Google Identity Services button container in the issue's headless repro) was never attached to the DOM. No error surfaced to Dart.

Before #179473 this path crashed loudly (#173401); since then it hangs silently.

Fix

  • C++/JS: skwasm_reportInitialized / surface_onInitialized gain a success flag. The failure path now reports initialization with success = false, and OnInitialized passes 0 (never a valid callback id, since ids start at ≥ 1 and the context-lost id is always ≥ 2) instead of the context-lost callback id. _skwasm_getGlContextForCanvas also returns 0 early when GL.createContext fails so it does not store key 0 in handleToCanvasMap or attach a webglcontextlost listener.
  • Dart: SkwasmSurface._initialize treats a 0 id as failure, sets _initializationFailed = true, and completes initialized with a StateError describing the WebGL2 failure instead of hanging. Subsequent rasterizeToImageBitmaps and setSize calls return early once _initializationFailed is set so later frames fail quietly rather than rethrowing on every frame, and onContextLost catches errors from recreateContextForCanvas so post-crash context recreation failures do not escape as duplicate unhandled async errors.
  • Test: new tests in test/ui/surface_context_lost_test.dart covering both initial WebGL context creation failure and context recreation failure after context loss.

Verification

  • Reproduced the hang with a headless Chrome harness using the reporter's GPU flags (skwasm, master): Failed to create context! in console, later-mounted flt-platform-view never attached. Default flags / --disable-gpu unaffected.
  • felt test --gcs-prod --suite chrome-force-st-dart2wasm-skwasm-ui test/ui/surface_context_lost_test.dart:
    • against stock prebuilt skwasm: new test fails with TimeoutException (the hang); existing 4 pass.
    • with the prebuilt skwasm.js glue patched to emulate this C++ change: 5/5 pass.
  • App-level with patched platform dill + emulated glue: clear Bad state: Skwasm failed to create a WebGL2 context… error instead of silent hang; no regression with default flags.

Note

I did not compile the C++/JS locally (no emsdk/gclient sync), so CI is the first real build of the skwasm and wimp (shares surface.cc) changes.

Related to #193223 (partial: headless/GPU-flags variant only; intentionally not Fixes, so merging won't close the issue)

Pre-launch Checklist

When skwasm fails to create a WebGL2 context for its OffscreenCanvas,
`Surface::ReceiveCanvasOnWorker` printed "Failed to create context!" and
returned without ever reporting back to the main thread. On the Dart side
`SkwasmSurface.initialized` never completed, so every frame awaited it
forever: nothing was rendered, platform views mounted after the first
frame were never injected into the DOM, and no error was surfaced.

- Thread a `success` flag through `skwasm_reportInitialized` /
  `surface_onInitialized`; on failure the callback context is 0 (valid
  context-lost callback ids are always non-zero).
- In `SkwasmSurface._initialize`, treat 0 as failure: log a
  `console.error` and complete `initialized` with a `StateError` so
  rendering fails fast and visibly.
- Add a regression test that forces WebGL context creation to fail by
  handing skwasm a canvas that already has a 2D context.

Fixes flutter#193223
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-web Owned by Web platform team labels Sep 24, 2026
@kevmoo kevmoo added the CICD Run CI/CD label Sep 24, 2026
Transferring an OffscreenCanvas that already has a 2d rendering context
to the raster worker via postMessage throws InvalidStateError, so the
NoWebGLOffscreenCanvasProvider trick only works single-threaded. The
chrome-force-st-dart2wasm-skwasm-ui suite still exercises the
ReceiveCanvasOnWorker -> OnInitialized failure path.
@kevmoo
kevmoo marked this pull request as ready for review September 25, 2026 18:01

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the Skwasm surface initialization to handle WebGL context creation failures. Instead of waiting indefinitely when WebGL context creation fails, the C++ surface implementation now reports the failure back to the Dart side, which completes the initialization completer with a StateError and logs an error message. A regression test has been added to verify this behavior using a mock canvas provider that fails WebGL context creation. There are no review comments, and I have no feedback to provide.

@kevmoo
kevmoo requested a review from eyebrowsoffire October 6, 2026 17:01
@kevmoo
kevmoo requested a review from harryterkelsen November 7, 2026 02:23
- Track `_initializationFailed` so `initialized` surfaces the `StateError` once and subsequent `rasterizeToImageBitmaps` / `setSize` calls return early.
- Drop the duplicate `console.error` call before completing `initialized` with `StateError`.
- Catch errors from `recreateContextForCanvas` in `onContextLost` and add a single-threaded test for post-context-loss recreation failure.
- Return `0` early from `_skwasm_getGlContextForCanvas` when `GL.createContext` fails.
- Dispose test surfaces with `addTearDown(surface.dispose)`.
@kevmoo

kevmoo commented Nov 10, 2026

Copy link
Copy Markdown
Contributor Author

Merged master to pick up #196310 (tool_tests_general fix) and the latest Google3 roll.

@kevmoo kevmoo added the autosubmit Merge PR when tree becomes green via auto submit App label Nov 11, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Nov 11, 2026
Merged via the queue into flutter:master with commit b5d9f2e Nov 11, 2026
21 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Nov 11, 2026
@kevmoo
kevmoo deleted the issue-193223 branch November 11, 2026 04:58
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Nov 11, 2026
flutter/flutter@fffd8c2...b98afb5

2026-11-11 [email protected] Roll Dart SDK from 172cf8f121c0 to 8f15c4ca2d41 (1 revision) (flutter/flutter#196367)
2026-11-11 [email protected] Roll Skia from 657283e78115 to cc4c54f752ba (5 revisions) (flutter/flutter#196365)
2026-11-11 [email protected] Roll Skia from 2605c4a9761c to 657283e78115 (1 revision) (flutter/flutter#196358)
2026-11-11 [email protected] Roll Dart SDK from 890c6d15334c to 172cf8f121c0 (1 revision) (flutter/flutter#196352)
2026-11-11 [email protected] [flutter_tools] Migrate general.shard project, runner, and web tests off globals (flutter/flutter#196128)
2026-11-11 [email protected] [flutter_tools] Migrate test helpers and integration tests off globals (flutter/flutter#196124)
2026-11-11 [email protected] [web] Report skwasm WebGL context creation failure instead of hanging (flutter/flutter#193293)
2026-11-11 [email protected] [flutter_tools] Migrate commands.shard tests off globals (flutter/flutter#196139)
2026-11-11 [email protected] [devicelab] Fix memory benchmark tap synchronization and swipe flakes (flutter/flutter#194457)
2026-11-11 [email protected] Roll Skia from 06062e36d938 to 2605c4a9761c (2 revisions) (flutter/flutter#196350)
2026-11-11 [email protected] Do not wait again for a closed mock event stream in tear down (flutter/flutter#196110)
2026-11-11 [email protected] [gen_l10n] Add `use-explicit-plural-values` option (flutter/flutter#194816)
2026-11-11 [email protected] Roll Skia from 7bd33f8a3b70 to 06062e36d938 (2 revisions) (flutter/flutter#196340)
2026-11-11 [email protected] Skip redundant work in plugin_test_* (flutter/flutter#196258)
2026-11-10 [email protected] Drop test_timeout_secs from shards that no longer need it (flutter/flutter#196277)
2026-11-10 [email protected] Roll Dart SDK from 15c1699d3eeb to 890c6d15334c (1 revision) (flutter/flutter#196321)
2026-11-10 [email protected] iOS: Extract FlutterPlatformViewsController platform-thread state to Obj-C (flutter/flutter#196142)
2026-11-10 [email protected] Remove `Mac web_tool_tests` and take new subshard builders out of bringup (flutter/flutter#196276)
2026-11-10 [email protected] Roll Skia from 9c3d43d8a04b to 7bd33f8a3b70 (12 revisions) (flutter/flutter#196317)
2026-11-10 [email protected] Take customer_testing_devtools out of bringup (flutter/flutter#196239)
2026-11-10 [email protected] Roll ICU from a0ea93436c52 to b09986242cfb (1 revision) (flutter/flutter#196316)
2026-11-10 [email protected] [flutter_tools] Avoid unlinking native_assets.json and handle EXDEV (flutter/flutter#196134)
2026-11-10 [email protected] Remove old `Windows tool_integration_tests` builders and take the new shards out of bringup (flutter/flutter#196275)
2026-11-10 [email protected] [SwiftPM] Disable tests for when settings fail to compile (flutter/flutter#196310)
2026-11-10 [email protected] Roll Fuchsia Test Scripts from PXc5D7S_q6sIYpfFJ... to oEU515sDqSTvD8Spx... (flutter/flutter#196289)
2026-11-10 [email protected] Fix ime insets animation jump (flutter/flutter#191453)
2026-11-10 [email protected] Link to original PR in automatic cherry-pick PRs (flutter/flutter#196130)
2026-11-10 [email protected] Roll Packages from 565c657 to 08faf64 (9 revisions) (flutter/flutter#196296)
2026-11-10 [email protected] Roll Skia from b11315d0a096 to 9c3d43d8a04b (45 revisions) (flutter/flutter#196295)
2026-11-10 [email protected] Replace type-specific window widgets with a single Window widget (flutter/flutter#196002)
2026-11-10 [email protected] Roll Dart SDK from a2baae273bb2 to 15c1699d3eeb (2 revisions) (flutter/flutter#196294)

If this roll has caused a breakage, revert this CL and set the roller
to dry run mode using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-web Owned by Web platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

web: skwasm (--wasm) silently fails to render async-appended platform-view content under real GPU acceleration

2 participants