Sitelet https://github.com/flutter/flutter/pull/191232
Skip to content

[web] Unify ui.Shader between CanvasKit and Skwasm - #191232

Merged
auto-submit[bot] merged 3 commits into
flutter:masterfrom
harryterkelsen:unify-shader
Aug 19, 2026
Merged

auto-submit[bot] merged 3 commits into
flutter:masterfrom
harryterkelsen:unify-shader

Conversation

@harryterkelsen

Copy link
Copy Markdown
Contributor

Refactors ui.Shader (including Gradient and ImageShader) to share core business logic between CanvasKit and Skwasm through the EngineShader layer. Backend-specific implementations are intentionally kept minimal, with both backends now only implementing BackendShader to provide the final native calls.

Part of #175630.

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Aug 17, 2026

@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 refactors the web engine's shader architecture by introducing unified EngineShader classes and abstract backend interfaces (BackendShader, BackendGradient, etc.) to decouple the frontend API from specific renderer implementations (CanvasKit and Skwasm). Feedback on these changes highlights potential memory leaks in both CanvasKit and Skwasm fragment shader samplers due to undisposed child image shaders, a missing filterQuality parameter forwarding in EngineFragmentShader.setImageSampler, and the compilation-out of color stop validations in release mode due to being wrapped in assert statements.

Comment thread engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/painting.dart Outdated
Comment thread engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/shaders.dart Outdated
Comment thread engine/src/flutter/lib/web_ui/lib/src/engine/primitives/shader.dart
Comment thread engine/src/flutter/lib/web_ui/lib/painting.dart Outdated
Comment thread engine/src/flutter/lib/web_ui/lib/painting.dart Outdated
Comment on lines +419 to +422
assert(() {
_validateColorStops(colors, colorStops);
return true;
}());

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.

medium

Redundant and Assert-Only Validation of Color Stops\n\nWrapping _validateColorStops in an assert means that this validation is completely compiled out in release mode.\n\nIn Flutter mobile, _validateColorStops is called unconditionally in Gradient factories to throw an ArgumentError if the inputs are invalid. Disabling this on the web in release mode causes a behavioral divergence between mobile and web, and could lead to silent failures or obscure native crashes in CanvasKit/Skia.\n\nPlease call _validateColorStops unconditionally.

    _validateColorStops(colors, colorStops);
References
  1. Check for potential regressions: Look for changes that might break existing functionality or introduce unexpected behavior in related areas. (link)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is how the native engine does it, so it should be fine to do it here as well.

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.

The native engine doesn't wrap this in an assert. See:

super._() {
_validateColorStops(colors, colorStops);
final Float32List colorsBuffer = _encodeWideColorList(colors);
final Float32List? colorStopsBuffer = colorStops == null
? null
: Float32List.fromList(colorStops);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oops, you're right. I changed it.

@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 Aug 17, 2026
Part of flutter#175630.

Refactors `ui.Shader` (including `Gradient` and `ImageShader`) to share core business logic between CanvasKit and Skwasm through the `EngineShader` layer. Backend-specific implementations are intentionally kept minimal, with both backends now only implementing `BackendShader` to provide the final native calls.
@flutter-dashboard

Copy link
Copy Markdown

CI had a failure that stopped further tests from running. We need to investigate to determine the root cause.

SHA at time of execution: 342c9d6.

Possible causes:

  • Configuration Changes: The .ci.yaml file might have been modified between the creation of this pull request and the start of this test run. This can lead to ci yaml validation errors.
  • Infrastructure Issues: Problems with the CI environment itself (e.g., quota) could have caused the failure.

A blank commit, or merging to head, will be required to resume running CI for this PR.

Error Details:

FormatException: ERROR: Mac_ios ios_debug_workflow is a new builder added. it needs to be marked bringup: true
If ci.yaml wasn't changed, try `git fetch upstream && git merge upstream/master`

Stack trace:

#0      CiYaml._validate (package:cocoon_service/src/model/ci_yaml/ci_yaml.dart:395:7)
#1      new CiYaml (package:cocoon_service/src/model/ci_yaml/ci_yaml.dart:128:7)
#2      new CiYamlSet (package:cocoon_service/src/model/ci_yaml/ci_yaml.dart:48:23)
#3      CiYamlFetcher._getCiYaml (package:cocoon_service/src/service/scheduler/ci_yaml_fetcher.dart:124:12)
<asynchronous suspension>
#4      Scheduler.getPresubmitTargets (package:cocoon_service/src/service/scheduler.dart:1088:20)
<asynchronous suspension>
#5      Scheduler._getTestsForStage (package:cocoon_service/src/service/scheduler.dart:1404:14)
<asynchronous suspension>
#6      Scheduler._runCiTestingStage (package:cocoon_service/src/service/scheduler.dart:1445:30)
<asynchronous suspension>
#7      Scheduler.proceedToCiTestingStage (package:cocoon_service/src/service/scheduler.dart:1554:7)
<asynchronous suspension>
#8      Scheduler._closeSuccessfulEngineBuildStage (package:cocoon_service/src/service/scheduler.dart:1351:5)
<asynchronous suspension>
#9      Scheduler.processCheckRunCompleted (package:cocoon_service/src/service/scheduler.dart:1277:11)
<asynchronous suspension>
#10     PresubmitSubscription._processBuild (package:cocoon_service/src/request_handlers/presubmit_subscription.dart:226:7)
<asynchronous suspension>
#11     PresubmitSubscription.post (package:cocoon_service/src/request_handlers/presubmit_subscription.dart:119:5)
<asynchronous suspension>
#12     RequestHandler.service (package:cocoon_service/src/request_handling/request_handler.dart:42:20)
<asynchronous suspension>
#13     SubscriptionHandler.service (package:cocoon_service/src/request_handling/subscription_handler.dart:134:5)
<asynchronous suspension>
#14     createServer.<anonymous closure> (package:cocoon_service/server.dart:462:7)
<asynchronous suspension>
#15     main.<anonymous closure>.<anonymous closure> (file:///app/app_dart/bin/gae_server.dart:192:9)
<asynchronous suspension>

@harryterkelsen
harryterkelsen requested a review from mdebbar August 18, 2026 19:12
Comment on lines +419 to +422
assert(() {
_validateColorStops(colors, colorStops);
return true;
}());

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.

The native engine doesn't wrap this in an assert. See:

super._() {
_validateColorStops(colors, colorStops);
final Float32List colorsBuffer = _encodeWideColorList(colors);
final Float32List? colorStopsBuffer = colorStops == null
? null
: Float32List.fromList(colorStops);

Comment thread engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/shader.dart Outdated
Comment thread engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/shader.dart Outdated
@harryterkelsen

Copy link
Copy Markdown
Contributor Author

Thanks @mdebbar, PTAL!

@mdebbar mdebbar 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

@harryterkelsen harryterkelsen added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 18, 2026
@auto-submit

auto-submit Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/191232, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 18, 2026
@harryterkelsen harryterkelsen added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 19, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Aug 19, 2026
Merged via the queue into flutter:master with commit 74b8f23 Aug 19, 2026
28 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 19, 2026
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.

2 participants