[web] Use thread local strike caches in skwasm by ColeSpringer · Pull Request #190048 · flutter/flutter · GitHub
Skip to content

[web] Use thread local strike caches in skwasm - #190048

Merged
auto-submit[bot] merged 13 commits into
flutter:masterfrom
ColeSpringer:fix-skwasm-hybrid-pthreads-190039
Aug 5, 2026
Merged

[web] Use thread local strike caches in skwasm#190048
auto-submit[bot] merged 13 commits into
flutter:masterfrom
ColeSpringer:fix-skwasm-hybrid-pthreads-190039

Conversation

@ColeSpringer

@ColeSpringer ColeSpringer commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Description

Multithreaded skwasm is built with -sWASM_WORKERS but without -pthread, which
links the single threaded emscripten system libraries where mutexes are no-ops.
Text layout on the main thread and the raster worker share the global
SkStrikeCache, so under heavy text churn the two threads corrupt the heap and
the tab ends up pinned at 100% CPU.

The fix is Skia's experimental thread local strike cache flag, enabled from a
constructor in surface.cc. Each thread gets its own strike cache, so there is no
shared state left to race on.

Two adjacent fixes:

  • context_lost_callback_id_ was allocated on the worker by incrementing
    current_callback_id_, which the main thread also increments. It is now
    allocated on the main thread in SetCanvas.
  • surface_setResourceCacheLimitBytes touched the worker owned GrDirectContext
    from the main thread. It now dispatches to the worker, and the value is stored
    and reapplied when the render context is recreated. This also fixes a null deref
    when Dart sets the limit before surface init.

Tests

New regression test lib/web_ui/test/skwasm/concurrent_text_layout_raster_test.dart:
text layout with never repeating font parameters on the main thread while the
worker rasterizes the previous frame, disposing everything per frame and toggling
the resource cache limit. Without the flag it fails 2 of 2 runs (one wasm timeout,
one hard page freeze); with it, 6 of 6 pass. The context loss suite passes 4 of 4,
covering the callback id and cache limit changes.

No golden churn is expected.

Fixes #190039
Possibly also fixes #184858, which looks like the same corruption from the dispose
path.

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@github-actions github-actions Bot added a: text input Entering text in a text field or keyboard related problems engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-web Owned by Web platform team labels Jul 27, 2026
@ColeSpringer
ColeSpringer marked this pull request as ready for review July 27, 2026 00:48

@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 introduces support for 'wasm_use_pthreads' in the build configuration and adds a concurrent text layout and rasterization test. It also dispatches resource cache limit updates to the raster worker thread in Skwasm, making 'current_callback_id_' atomic to support multi-threaded access. The reviewer recommends persistently storing the resource cache limit on the surface rather than clearing it after the initial setup, ensuring the limit is preserved if the render context is recreated.

Comment thread engine/src/flutter/skwasm/surface.cc
Comment thread engine/src/flutter/skwasm/surface.cc Outdated
Comment thread engine/src/flutter/skwasm/surface.h Outdated
@ColeSpringer
ColeSpringer force-pushed the fix-skwasm-hybrid-pthreads-190039 branch from fa1d523 to d64e4b3 Compare July 27, 2026 00:57
Multithreaded skwasm was built with -sWASM_WORKERS but without
-pthread, which links emscripten's single-threaded stub system
libraries: every lock in Skia, FreeType, and libc++ was a no-op while
two threads shared linear memory, corrupting the heap under concurrent
text layout and rasterization.

Add a wasm_use_pthreads GN arg that links the pthread-enabled "-mt"
system libraries while still creating threads as wasm workers, and
enable it for the skwasm toolchains. Also make the cross-thread
callback id atomic, dispatch surface_setResourceCacheLimitBytes to the
raster worker that owns the render context, and add a regression test
driving concurrent text layout and rasterization.

Fixes #190039
@ColeSpringer
ColeSpringer force-pushed the fix-skwasm-hybrid-pthreads-190039 branch from d64e4b3 to 3f0a645 Compare July 27, 2026 17:31
@kevmoo
kevmoo requested a review from eyebrowsoffire July 27, 2026 22:57
@Renzo-Olivares Renzo-Olivares removed the a: text input Entering text in a text field or keyboard related problems label Jul 30, 2026
@github-actions github-actions Bot added the a: text input Entering text in a text field or keyboard related problems label Jul 31, 2026
@eyebrowsoffire

Copy link
Copy Markdown
Contributor

@eyebrowsoffire

Copy link
Copy Markdown
Contributor

Also, I was looking at the change which makes _currentCallbackId an atomic. This should only ever be modified on the main thread. I see that you pointed out that this is modified in the ReceiveCanvasOnWorker function, which happens in the web worker, so that is not correct. I traced through the code and it looks like we modify the callback ID and pass a context_lost_callback_id_ around with this, but soon after that we just drop this value on the ground when we bounce back to the main thread (we attach the value to the onInitiailized message, but then when we receive the message on the main thread we don't do anything with it). So actually this doesn't seem to be doing anything, and we can probably just remove the context_lost_callback_id_ and the associated arguments and that will remove the only place where we modify _currentCallbackId on the web worker, which resolves the race condition.

@ColeSpringer

Copy link
Copy Markdown
Contributor Author

@eyebrowsoffire Went ahead and switched out the pthreads implementation with the skia flag you mentioned. Ran the tests with the flag off and the issue reappeared (tests failed). Running with the flag on resulted in all of the tests passing.

Comment thread engine/src/flutter/skwasm/surface.cc
@harryterkelsen
harryterkelsen self-requested a review August 4, 2026 19:33

@harryterkelsen harryterkelsen 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.

LGTM. I think it's safe to use the experimental flag here. According to discussions with the Skia team, the flag is mostly safe, but not turned on by default because it breaks specific Chrome non-standard use cases. We should be okay using it.

@harryterkelsen

Copy link
Copy Markdown
Contributor

Please update the title of the PR to reflect the actual fix (enabling the experimental flag)

@eyebrowsoffire eyebrowsoffire 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.

I agree with @harryterkelsen, I think we should actually just land this. As he mentioned, please update the PR description and title so that the commit message is accurate.

@ColeSpringer ColeSpringer changed the title [web] Link multithreaded skwasm in emscripten hybrid mode [web] Use thread local strike caches in skwasm Aug 4, 2026
@ColeSpringer

Copy link
Copy Markdown
Contributor Author

PR title and description updated.

@harryterkelsen harryterkelsen added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 4, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Aug 5, 2026
Merged via the queue into flutter:master with commit d3ac5cd Aug 5, 2026
30 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 5, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Aug 10, 2026
…12420)

Manual roll requested by stuartmorgan@google.com

flutter/flutter@b766512...27b0988

2026-08-05 kevmoo@users.noreply.github.com reland(tool): remove redundant --enable-experiment=record-use flag (flutter/flutter#190591)
2026-08-05 chris@bracken.jp Windows: Propagate enabled accessibility state (flutter/flutter#190507)
2026-08-05 engine-flutter-autoroll@skia.org Roll Fuchsia Test Scripts from ltbuIH9Z3T_yOuigu... to vcANVO8VIDQHasH1X... (flutter/flutter#190589)
2026-08-05 256906086+mvincentong@users.noreply.github.com Document frozen embedder API structs (flutter/flutter#186842)
2026-08-05 49402500+fahaddoc@users.noreply.github.com Document super call order for State.didChangeDependencies (flutter/flutter#185945)
2026-08-05 dkwingsmt@users.noreply.github.com Move examples of `flutter/widgets` widgets out from `flutter/material` (flutter/flutter#189532)
2026-08-05 93888664+ColeSpringer@users.noreply.github.com [web] Use thread local strike caches in skwasm (flutter/flutter#190048)
2026-08-05 43089218+chika3742@users.noreply.github.com doc: fix typo in see also section for PrimaryScrollController.maybeOf (flutter/flutter#190386)
2026-08-05 jason-simmons@users.noreply.github.com Migrate the shell unit tests from legacy Dart native functions to FFI (flutter/flutter#190473)
2026-08-05 47866232+chunhtai@users.noreply.github.com render proxy box now defaults baseline calculation to null (flutter/flutter#190269)
2026-08-05 36861262+QuncCccccc@users.noreply.github.com Update Widgets Localizations from Translation Console (flutter/flutter#190503)
2026-08-04 154381524+flutteractionsbot@users.noreply.github.com Revert: fix(tool): remove redundant --enable-experiment=record-use flag (flutter/flutter#190583)
2026-08-04 engine-flutter-autoroll@skia.org Roll Fuchsia Test Scripts from 1frGe_KltAJKkeyPg... to ltbuIH9Z3T_yOuigu... (flutter/flutter#190561)
2026-08-04 chris@bracken.jp iOS,macOS: add tsan and ubsan support for Swift (flutter/flutter#190497)
2026-08-04 34465683+rkishan516@users.noreply.github.com fix: update on_message_ to nullptr after window destroy so that dart gets destroy message  (flutter/flutter#185807)
2026-08-04 bkonyi@google.com [flutter_tools] Gracefully handle locked Windows files during clean (flutter/flutter#190095)
2026-08-04 chris@bracken.jp iOS,macOS: make Logger thread-safe, conform to Sendable (flutter/flutter#190488)
2026-08-04 chris@bracken.jp iOS: Eliminate use of IOSContextNoop in platform view tests (reland) (flutter/flutter#190509)
2026-08-04 kevmoo@users.noreply.github.com fix(tool): remove redundant --enable-experiment=record-use flag (flutter/flutter#190475)
2026-08-04 awolff@google.com android_hardware_smoke_test: Detect blank image failures or EGL initialization warnings and retry (flutter/flutter#190110)
2026-08-04 30870216+gaaclarke@users.noreply.github.com Bumps text gamma on windows to match skia. (flutter/flutter#190477)
2026-08-04 engine-flutter-autoroll@skia.org Roll Skia from 48b58ee222f1 to a8583a0a2c11 (2 revisions) (flutter/flutter#190537)
2026-08-04 kevmoo@users.noreply.github.com [tool][web] Intercept dart2wasm errors & append JS migration footers (flutter/flutter#190476)
2026-08-04 dacoharkes@google.com [record_use] Migrate IconTreeShaker to `package:record_use` (flutter/flutter#190225)
2026-08-04 s4bre.py@gmail.com Handle unexpected exceptions during Azure metadata detection (flutter/flutter#189457)
2026-08-04 15619084+vashworth@users.noreply.github.com Fix merge conflict from flutter/flutter#190369 (flutter/flutter#190544)
2026-08-04 15619084+vashworth@users.noreply.github.com Prepare device support symbols (flutter/flutter#190369)
2026-08-04 engine-flutter-autoroll@skia.org Roll Packages from ac87e65 to 3498b9d (1 revision) (flutter/flutter#190532)
2026-08-04 engine-flutter-autoroll@skia.org Roll Skia from a08d918ebd6a to 48b58ee222f1 (11 revisions) (flutter/flutter#190527)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC stuartmorgan@google.com,tarrinneal@google.com 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
@ashishchauhan-x

Copy link
Copy Markdown

pull Bot pushed a commit to AbhiShake1/flutter that referenced this pull request Aug 20, 2026
After flutter#190048, we no longer have
multthreading issues with wimp, so we should turn multithreading on.

This addresses flutter#178749
pull Bot pushed a commit to safarmer/flutter that referenced this pull request Aug 20, 2026
Reverts: [[wimp] Turn multithreading on for
wimp.](flutter#190626)

Initiated by: @bkonyi

Reason for reverting: [failing Linux linux_web_engine_tests on
tree](https://ci.chromium.org/ui/p/flutter/builders/prod/Linux%20linux_web_engine_tests/9022).

Original PR Author: @eyebrowsoffire

Reviewed By: @mdebbar

The original PR description is provided below:

After flutter#190048, we no longer have
multthreading issues with wimp, so we should turn multithreading on.

This addresses flutter#178749
GhagSagar23 pushed a commit to GhagSagar23/flutter that referenced this pull request Aug 20, 2026
Reverts: [[wimp] Turn multithreading on for
wimp.](flutter#190626)

Initiated by: @bkonyi

Reason for reverting: [failing Linux linux_web_engine_tests on
tree](https://ci.chromium.org/ui/p/flutter/builders/prod/Linux%20linux_web_engine_tests/9022).

Original PR Author: @eyebrowsoffire

Reviewed By: @mdebbar

The original PR description is provided below:

After flutter#190048, we no longer have
multthreading issues with wimp, so we should turn multithreading on.

This addresses flutter#178749
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: text input Entering text in a text field or keyboard related problems 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

5 participants