Skip to content

Apps package the engine shader bundles twice (data asset plus flutter_scene_generated copy) #354

Open

Description

@bdero

Every app ships the engine's shader bundles twice. Found while measuring the bundle-size impact of #353 on examples/smoke_render (arm64 debug APK, master 93d420be).

What the APK contains

assets/flutter_assets/packages/flutter_scene/flutter_gpu_shaders/shaderbundles/base.shaderbundle      1,400,896 raw / 372,054 deflated
assets/flutter_assets/flutter_scene_generated/shaderbundle.base.ea6ec455.shaderbundle                 1,400,896 raw / 372,054 deflated  (byte-identical)
assets/flutter_assets/packages/flutter_scene/flutter_scene/fmat/physical/physical.shaderbundle        3,283,192 raw / 850,664 deflated
assets/flutter_assets/flutter_scene_generated/material.physical.86d5a369.shaderbundle                 3,283,192 raw / 850,664 deflated  (byte-identical)

That is about 1.2 MB of deflated download (4.7 MB on disk) duplicated per app. The macOS debug bundle shows the same pair in flutter_assets/.

Why

flutter_scene's own build hook registers base.shaderbundle and physical.shaderbundle as Dart data assets (packages/flutter_scene/flutter_gpu_shaders/shaderbundles/... and packages/flutter_scene/flutter_scene/fmat/physical/...), and the runtime prefers those keys (shaders.dart, physical_material_variant.dart, see engine_bundle_keys_test.dart for the three-way resolution). The app's hook independently writes the same bundles into flutter_scene_generated/, and dart run flutter_scene:init lists that whole directory under flutter.assets, so both copies land in the app.

The fallback chain exists so a toolchain without data-asset support still works, but when data assets are available the generated copies of the two engine bundles are dead weight (only the app's own .fmat materials and any app .shaderbundle.json need the generated directory).

Proposal

When the hook registers the engine bundles as data assets, skip writing them into the app's flutter_scene_generated/ (or write them somewhere outside the packaged directory), so an app ships one copy. Keep the generated-tree fallback for toolchains without data assets. A test asserting the built flutter_assets holds exactly one base.shaderbundle would keep it from regressing.

Related lever, impellerc's SPIR-V keeps the OpName/OpLine debug decorations (687 on the standard entry); stripping them would shrink every Vulkan entry in every bundle.

Activity

  1. added
    bugSomething isn't working.
    buildProject building
    on Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working.buildProject building

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions