diff --git a/packages/flutter_tools/lib/src/build_system/targets/ios.dart b/packages/flutter_tools/lib/src/build_system/targets/ios.dart index 9d54b55d12..a58399fa02 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/ios.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/ios.dart @@ -511,22 +511,14 @@ abstract class IosAssetBundle extends Target { final FlutterProject flutterProject = FlutterProject.fromDirectory(environment.projectDir); - bool isImpellerEnabled() { - if (!flutterProject.ios.infoPlist.existsSync()) { - return false; - } - final Map info = globals.plistParser.parseFile(flutterProject.ios.infoPlist.path); - - final Object? enableImpeller = info['FLTEnableImpeller']; - return enableImpeller is bool && enableImpeller; - } - // Copy the assets. final Depfile assetDepfile = await copyAssets( environment, assetDirectory, targetPlatform: TargetPlatform.ios, - shaderTarget: isImpellerEnabled() ? ShaderTarget.impelleriOS : ShaderTarget.sksl, + // Always specify an impeller shader target so that we support runtime toggling and + // the --enable-impeller debug flag. + shaderTarget: ShaderTarget.impelleriOS, additionalInputs: [ flutterProject.ios.infoPlist, flutterProject.ios.appFrameworkInfoPlist, diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart index d84b0d8063..15d3265c61 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart @@ -217,6 +217,78 @@ void main() { expect(assetDirectory.childFile('isolate_snapshot_data'), exists); expect(assetDirectory.childFile('io.flutter.shaders.json'), exists); expect(assetDirectory.childFile('io.flutter.shaders.json').readAsStringSync(), '{"data":{"A":"B"}}'); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => processManager, + Platform: () => macPlatform, + }); + + testUsingContext('DebugIosApplicationBundle with impeller and shader compilation', () async { + // Create impellerc to work around fallback detection logic. + fileSystem.file(artifacts.getHostArtifact(HostArtifact.impellerc)).createSync(recursive: true); + + environment.defines[kBuildMode] = 'debug'; + environment.defines[kCodesignIdentity] = 'ABC123'; + // Precompiled dart data + + fileSystem.file(artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug)) + .createSync(); + fileSystem.file(artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug)) + .createSync(); + // Project info + fileSystem.file('pubspec.yaml').writeAsStringSync('name: hello\nflutter:\n shaders:\n - shader.glsl'); + fileSystem.file('.packages').writeAsStringSync('\n'); + // Plist file + fileSystem.file(fileSystem.path.join('ios', 'Flutter', 'AppFrameworkInfo.plist')) + .createSync(recursive: true); + // Shader file + fileSystem.file('shader.glsl').writeAsStringSync('test'); + // App kernel + environment.buildDir.childFile('app.dill').createSync(recursive: true); + // Stub framework + environment.buildDir + .childDirectory('App.framework') + .childFile('App') + .createSync(recursive: true); + + final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework'); + final File frameworkDirectoryBinary = frameworkDirectory.childFile('App'); + processManager.addCommands([ + const FakeCommand(command: [ + 'HostArtifact.impellerc', + '--runtime-stage-metal', + '--iplr', + '--sl=/App.framework/flutter_assets/shader.glsl', + '--spirv=/App.framework/flutter_assets/shader.glsl.spirv', + '--input=/shader.glsl', + '--input-type=frag', + '--include=/' + ]), + FakeCommand(command: [ + 'codesign', + '--force', + '--sign', + 'ABC123', + '--timestamp=none', + frameworkDirectoryBinary.path, + ]), + ]); + + await const DebugIosApplicationBundle().build(environment); + expect(processManager, hasNoRemainingExpectations); + + expect(frameworkDirectoryBinary, exists); + expect(frameworkDirectory.childFile('Info.plist'), exists); + + final Directory assetDirectory = frameworkDirectory.childDirectory('flutter_assets'); + expect(assetDirectory.childFile('kernel_blob.bin'), exists); + expect(assetDirectory.childFile('AssetManifest.json'), exists); + expect(assetDirectory.childFile('vm_snapshot_data'), exists); + expect(assetDirectory.childFile('isolate_snapshot_data'), exists); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => processManager, + Platform: () => macPlatform, }); testUsingContext('ReleaseIosApplicationBundle build', () async {