Skip to content

Commit 47f08a3

Browse files
authored
[flutter_tool] Adds --enable-impeller flag to the run command (#100835)
1 parent 689672f commit 47f08a3

File tree

9 files changed

+70
-1
lines changed

9 files changed

+70
-1
lines changed

packages/flutter_tools/lib/src/commands/run.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
140140
'startup. By default this is main(List<String> args). Specify '
141141
'this option multiple times each with one argument to pass '
142142
'multiple arguments to the Dart entrypoint. Currently this is '
143-
'only supported on desktop platforms.'
143+
'only supported on desktop platforms.',
144144
);
145145
usesWebOptions(verboseHelp: verboseHelp);
146146
usesTargetOption();
@@ -155,6 +155,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
155155
addDevToolsOptions(verboseHelp: verboseHelp);
156156
addAndroidSpecificBuildOptions(hide: !verboseHelp);
157157
usesFatalWarningsOption(verboseHelp: verboseHelp);
158+
addEnableImpellerFlag(verboseHelp: verboseHelp);
158159
}
159160

160161
bool get traceStartup => boolArg('trace-startup');
@@ -164,6 +165,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
164165
bool get disableServiceAuthCodes => boolArg('disable-service-auth-codes');
165166
bool get runningWithPrebuiltApplication => argResults['use-application-binary'] != null;
166167
bool get trackWidgetCreation => boolArg('track-widget-creation');
168+
bool get enableImpeller => boolArg('enable-impeller');
167169

168170
@override
169171
bool get reportNullSafety => true;
@@ -193,6 +195,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
193195
webEnableExposeUrl: featureFlags.isWebEnabled && boolArg('web-allow-expose-url'),
194196
webRunHeadless: featureFlags.isWebEnabled && boolArg('web-run-headless'),
195197
webBrowserDebugPort: browserDebugPort,
198+
enableImpeller: enableImpeller,
196199
);
197200
} else {
198201
return DebuggingOptions.enabled(
@@ -235,6 +238,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
235238
&& !runningWithPrebuiltApplication,
236239
nullAssertions: boolArg('null-assertions'),
237240
nativeNullAssertions: boolArg('native-null-assertions'),
241+
enableImpeller: enableImpeller,
238242
);
239243
}
240244
}
@@ -438,6 +442,7 @@ class RunCommand extends RunCommandBase {
438442
commandRunProjectModule: FlutterProject.current().isModule,
439443
commandRunProjectHostLanguage: hostLanguage.join(','),
440444
commandRunAndroidEmbeddingVersion: androidEmbeddingVersion,
445+
commandRunEnableImpeller: enableImpeller,
441446
);
442447
}
443448

packages/flutter_tools/lib/src/device.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,7 @@ class DebuggingOptions {
790790
this.fastStart = false,
791791
this.nullAssertions = false,
792792
this.nativeNullAssertions = false,
793+
this.enableImpeller = false,
793794
}) : debuggingEnabled = true;
794795

795796
DebuggingOptions.disabled(this.buildInfo, {
@@ -805,6 +806,7 @@ class DebuggingOptions {
805806
this.webLaunchUrl,
806807
this.cacheSkSL = false,
807808
this.traceAllowlist,
809+
this.enableImpeller = false,
808810
}) : debuggingEnabled = false,
809811
useTestFonts = false,
810812
startPaused = false,
@@ -870,6 +872,7 @@ class DebuggingOptions {
870872
required this.fastStart,
871873
required this.nullAssertions,
872874
required this.nativeNullAssertions,
875+
required this.enableImpeller,
873876
});
874877

875878
final bool debuggingEnabled;
@@ -903,6 +906,7 @@ class DebuggingOptions {
903906
final bool webUseSseForDebugProxy;
904907
final bool webUseSseForDebugBackend;
905908
final bool webUseSseForInjectedClient;
909+
final bool enableImpeller;
906910

907911
/// Whether to run the browser in headless mode.
908912
///
@@ -972,6 +976,7 @@ class DebuggingOptions {
972976
'fastStart': fastStart,
973977
'nullAssertions': nullAssertions,
974978
'nativeNullAssertions': nativeNullAssertions,
979+
'enableImpeller': enableImpeller,
975980
};
976981

977982
static DebuggingOptions fromJson(Map<String, Object?> json, BuildInfo buildInfo) =>
@@ -1014,6 +1019,7 @@ class DebuggingOptions {
10141019
fastStart: (json['fastStart'] as bool?)!,
10151020
nullAssertions: (json['nullAssertions'] as bool?)!,
10161021
nativeNullAssertions: (json['nativeNullAssertions'] as bool?)!,
1022+
enableImpeller: (json['enableImpeller'] as bool?) ?? false,
10171023
);
10181024
}
10191025

packages/flutter_tools/lib/src/ios/devices.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ class IOSDevice extends Device {
373373
if (debuggingOptions.purgePersistentCache) '--purge-persistent-cache',
374374
if (route != null) '--route=$route',
375375
if (platformArgs['trace-startup'] as bool? ?? false) '--trace-startup',
376+
if (debuggingOptions.enableImpeller) '--enable-impeller',
376377
];
377378

378379
final Status installStatus = _logger.startProgress(

packages/flutter_tools/lib/src/reporting/custom_dimensions.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class CustomDimensions {
6666
this.hotEventScannedSourcesCount,
6767
this.hotEventReassembleTimeInMs,
6868
this.hotEventReloadVMTimeInMs,
69+
this.commandRunEnableImpeller,
6970
});
7071

7172
final String? sessionHostOsDetails; // cd1
@@ -123,6 +124,7 @@ class CustomDimensions {
123124
final int? hotEventScannedSourcesCount; // cd 53
124125
final int? hotEventReassembleTimeInMs; // cd 54
125126
final int? hotEventReloadVMTimeInMs; // cd 55
127+
final bool? commandRunEnableImpeller; // cd 56
126128

127129
/// Convert to a map that will be used to upload to the analytics backend.
128130
Map<String, String> toMap() => <String, String>{
@@ -181,6 +183,7 @@ class CustomDimensions {
181183
if (hotEventScannedSourcesCount != null) cdKey(CustomDimensionsEnum.hotEventScannedSourcesCount): hotEventScannedSourcesCount.toString(),
182184
if (hotEventReassembleTimeInMs != null) cdKey(CustomDimensionsEnum.hotEventReassembleTimeInMs): hotEventReassembleTimeInMs.toString(),
183185
if (hotEventReloadVMTimeInMs != null) cdKey(CustomDimensionsEnum.hotEventReloadVMTimeInMs): hotEventReloadVMTimeInMs.toString(),
186+
if (commandRunEnableImpeller != null) cdKey(CustomDimensionsEnum.commandRunEnableImpeller): commandRunEnableImpeller.toString(),
184187
};
185188

186189
/// Merge the values of two [CustomDimensions] into one. If a value is defined
@@ -246,6 +249,7 @@ class CustomDimensions {
246249
hotEventScannedSourcesCount: other.hotEventScannedSourcesCount ?? hotEventScannedSourcesCount,
247250
hotEventReassembleTimeInMs: other.hotEventReassembleTimeInMs ?? hotEventReassembleTimeInMs,
248251
hotEventReloadVMTimeInMs: other.hotEventReloadVMTimeInMs ?? hotEventReloadVMTimeInMs,
252+
commandRunEnableImpeller: other.commandRunEnableImpeller ?? commandRunEnableImpeller,
249253
);
250254
}
251255

@@ -305,6 +309,7 @@ class CustomDimensions {
305309
hotEventScannedSourcesCount: _extractInt(map, CustomDimensionsEnum.hotEventScannedSourcesCount),
306310
hotEventReassembleTimeInMs: _extractInt(map, CustomDimensionsEnum.hotEventReassembleTimeInMs),
307311
hotEventReloadVMTimeInMs: _extractInt(map, CustomDimensionsEnum.hotEventReloadVMTimeInMs),
312+
commandRunEnableImpeller: _extractBool(map, CustomDimensionsEnum.commandRunEnableImpeller),
308313
);
309314

310315
static bool? _extractBool(Map<String, String> map, CustomDimensionsEnum field) =>
@@ -390,6 +395,7 @@ enum CustomDimensionsEnum {
390395
hotEventScannedSourcesCount, // cd53
391396
hotEventReassembleTimeInMs, // cd54
392397
hotEventReloadVMTimeInMs, // cd55
398+
commandRunEnableImpeller, // cd56
393399
}
394400

395401
String cdKey(CustomDimensionsEnum cd) => 'cd${cd.index + 1}';

packages/flutter_tools/lib/src/runner/flutter_command.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,16 @@ abstract class FlutterCommand extends Command<void> {
948948
);
949949
}
950950

951+
void addEnableImpellerFlag({required bool verboseHelp}) {
952+
argParser.addFlag('enable-impeller',
953+
negatable: false,
954+
hide: !verboseHelp,
955+
help: 'Whether to enable the experimental Impeller rendering engine. '
956+
'Impeller is currently only supported on iOS. This flag will '
957+
'be ignored when targeting other platforms.',
958+
);
959+
}
960+
951961
/// Compute the [BuildInfo] for the current flutter command.
952962
/// Commands that build multiple build modes can pass in a [forcedBuildMode]
953963
/// to be used instead of parsing flags.

packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,26 @@ void main() {
207207
ProcessManager: () => FakeProcessManager.any(),
208208
Pub: () => FakePub(),
209209
});
210+
211+
testUsingContext('--enable-impeller flag propagates to debugging options', () async {
212+
final DriveCommand command = DriveCommand(fileSystem: fileSystem, logger: logger, platform: platform);
213+
fileSystem.file('lib/main.dart').createSync(recursive: true);
214+
fileSystem.file('test_driver/main_test.dart').createSync(recursive: true);
215+
fileSystem.file('pubspec.yaml').createSync();
216+
217+
await expectLater(() => createTestCommandRunner(command).run(<String>[
218+
'drive',
219+
'--enable-impeller',
220+
]), throwsToolExit());
221+
222+
final DebuggingOptions options = await command.createDebuggingOptions(false);
223+
224+
expect(options.enableImpeller, true);
225+
}, overrides: <Type, Generator>{
226+
Cache: () => Cache.test(processManager: FakeProcessManager.any()),
227+
FileSystem: () => MemoryFileSystem.test(),
228+
ProcessManager: () => FakeProcessManager.any(),
229+
});
210230
}
211231

212232
// Unfortunately Device, despite not being immutable, has an `operator ==`.

packages/flutter_tools/test/commands.shard/hermetic/run_test.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ void main() {
394394
TestUsageCommand('run', parameters: CustomDimensions.fromMap(<String, String>{
395395
'cd3': 'false', 'cd4': 'ios', 'cd22': 'iOS 13',
396396
'cd23': 'debug', 'cd18': 'false', 'cd15': 'swift', 'cd31': 'false',
397+
'cd56': 'false',
397398
})
398399
)));
399400
}, overrides: <Type, Generator>{
@@ -622,6 +623,22 @@ void main() {
622623
ProcessManager: () => FakeProcessManager.any(),
623624
});
624625

626+
testUsingContext('--enable-impeller flag propagates to debugging options', () async {
627+
final RunCommand command = RunCommand();
628+
await expectLater(() => createTestCommandRunner(command).run(<String>[
629+
'run',
630+
'--enable-impeller',
631+
]), throwsToolExit());
632+
633+
final DebuggingOptions options = await command.createDebuggingOptions(false);
634+
635+
expect(options.enableImpeller, true);
636+
}, overrides: <Type, Generator>{
637+
Cache: () => Cache.test(processManager: FakeProcessManager.any()),
638+
FileSystem: () => MemoryFileSystem.test(),
639+
ProcessManager: () => FakeProcessManager.any(),
640+
});
641+
625642
testUsingContext('fails when "--web-launch-url" is not supported', () async {
626643
final RunCommand command = RunCommand();
627644
await expectLater(

packages/flutter_tools/test/general.shard/device_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,7 @@ void main() {
521521
dartEntrypointArgs: <String>['a', 'b'],
522522
dartFlags: 'c',
523523
deviceVmServicePort: 1234,
524+
enableImpeller: true,
524525
);
525526
final String jsonString = json.encode(original.toJson());
526527
final Map<String, dynamic> decoded = castStringKeyedMap(json.decode(jsonString))!;
@@ -531,6 +532,7 @@ void main() {
531532
expect(deserialized.dartEntrypointArgs, original.dartEntrypointArgs);
532533
expect(deserialized.dartFlags, original.dartFlags);
533534
expect(deserialized.deviceVmServicePort, original.deviceVmServicePort);
535+
expect(deserialized.enableImpeller, original.enableImpeller);
534536
});
535537
});
536538
}

packages/flutter_tools/test/general.shard/ios/ios_device_start_prebuilt_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ void main() {
285285
'--verbose-logging',
286286
'--cache-sksl',
287287
'--purge-persistent-cache',
288+
'--enable-impeller',
288289
].join(' '),
289290
], environment: const <String, String>{
290291
'PATH': '/usr/bin:null',
@@ -332,6 +333,7 @@ void main() {
332333
purgePersistentCache: true,
333334
verboseSystemLogs: true,
334335
nullAssertions: true,
336+
enableImpeller: true,
335337
),
336338
platformArgs: <String, dynamic>{},
337339
);

0 commit comments

Comments
 (0)