fix: bundle fragment shaders with the Metal runtime stage#34
Conversation
MAUstaoglu
left a comment
There was a problem hiding this comment.
Diffed the new TvosCopyFlutterBundle.build line-by-line against upstream CopyFlutterBundle.build in the pinned SDK (e1fd963) — it's a faithful mirror with exactly the two intended deltas:
- the empty-
native_assets.jsonshim is written first (folded in from the previous override, since we skip the native-assets targets), and copyAssets(... targetPlatform: TargetPlatform.ios ...)instead of upstream's hard-codedTargetPlatform.android.
The reasoning holds: targetPlatform drives ShaderCompiler._shaderTargetsFromTargetPlatform, and only the ios target emits the Metal runtime stage the tvOS engine (Impeller/Metal) needs. Upstream can hard-code android here because on real iOS the release asset copy runs through ReleaseIosApplicationBundle with ios; tvOS routes every build mode through this target, which is why the android-stage shaders were failing at load with "does not contain appropriate runtime stage data for current backend (Metal)".
All five added imports (depfile, assets, native_assets, devfs, dart_hook_result) resolve in the pinned SDK and are each used (Depfile, copyAssets, DartBuild.loadHookResult, DevFSContent/DevFSFileContent, DartHooksResult).
The doc comment correctly records the maintenance contract (re-mirror on Flutter upgrades) alongside the existing TvosKernelSnapshot note. As flagged, this shares the import block with #33 — whichever lands second gets a trivial rebase.
Approving.
|
Approved, but this now conflicts with the base after #33 merged into |
TvosCopyFlutterBundle inherited upstream CopyFlutterBundle.build, which hard-codes targetPlatform: TargetPlatform.android for copyAssets. The target platform drives impellerc's runtime-stage flags, so every fragment shader was bundled with SkSL/GLES/Vulkan stages only — and the tvOS engine renders with Impeller/Metal, so all shaders failed at runtime with: Exception: Asset '....frag' does not contain appropriate runtime stage data for current backend (Metal). Found stages: SkSL OpenGLES OpenGLES3 Vulkan Upstream can hard-code android because on real iOS the release asset copy happens in ReleaseIosApplicationBundle, which passes ios — but tvOS bundles assets through CopyFlutterBundle for every build mode. Mirror upstream CopyFlutterBundle.build in TvosCopyFlutterBundle (same maintenance contract as TvosKernelSnapshot: re-mirror on Flutter upgrades) with targetPlatform: TargetPlatform.ios, so shaders get the Metal runtime stage. This also stops requesting SkSL, which some shaders (e.g. ones using fwidth or array initializers) can never compile to anyway. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
c14c034 to
98f4243
Compare
|
Rebased onto |
Problem
TvosCopyFlutterBundleinherits upstreamCopyFlutterBundle.build, which hard-codestargetPlatform: TargetPlatform.androidforcopyAssets. The target platform drives impellerc's runtime-stage flags (ShaderCompiler._shaderTargetsFromTargetPlatform): android yields SkSL/GLES/Vulkan stages, ios yields the Metal stage. Upstream can hard-code android because on real iOS the release asset copy happens inReleaseIosApplicationBundle, which passes ios — but tvOS bundles assets throughCopyFlutterBundlein every build mode, and the tvOS engine renders with Impeller/Metal.The result: every fragment shader in a tvOS app bundle fails at load time with
As a side effect, the build also emits impellerc SkSL-compilation warnings for shaders that can never target SkSL (e.g. ones using
fwidthor array initializers), even though that stage is useless on tvOS.Fix
TvosCopyFlutterBundle.buildnow mirrors upstreamCopyFlutterBundle.build(same maintenance contract asTvosKernelSnapshot: re-mirror on Flutter upgrades) with one change —copyAssetsreceivestargetPlatform: TargetPlatform.ios, so shaders are bundled with the Metal runtime stage. The existing empty-native_assets.jsonshim is folded into the mirrored body.Testing
flutter/bin/dart analyze lib/— no new issues vs unmodifiedmain.flutter/bin/dart test— identical results with and without the change (the failures in my environment reproduce byte-for-byte on unmodifiedmain; unrelated).FragmentProgram.fromAssetfailed with the error above; after, the bundled.fragassets contain the Metal stage (MSL source present, GLES/Vulkan stages absent) and load correctly on the Apple TV simulator. The spurious SkSL impellerc warnings are gone as well.Note: touches the same import block in
lib/build_targets/application.dartas #33, so whichever merges second needs a trivial rebase.🤖 Generated with Claude Code