Skip to content

Commit

Permalink
[benchmarks] disable partial repaint for multiple backdrop blur iOS m…
Browse files Browse the repository at this point in the history
…acrobenchmarks. (#137902)

Partial repaint is too effective, and we'd like to be able to measure performance without carefully structuring the benchmarks. For example, right now partial repaint is culling any blurs in the multibackdrop case, which we should be using to track  flutter/flutter#132735
  • Loading branch information
jonahwilliams authored Nov 6, 2023
1 parent f5a9835 commit 925f3ee
Showing 1 changed file with 86 additions and 8 deletions.
94 changes: 86 additions & 8 deletions dev/devicelab/lib/tasks/perf_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ TaskFunction createBackdropFilterPerfTest({
testDriver: 'test_driver/backdrop_filter_perf_test.dart',
saveTraceFile: true,
enableImpeller: enableImpeller,
disablePartialRepaint: true,
).run;
}

Expand Down Expand Up @@ -767,6 +768,51 @@ Map<String, dynamic> _average(List<Map<String, dynamic>> results, int iterations
return tally;
}

/// Opens the file at testDirectory + 'ios/Runner/Info.plist'
/// and adds the following entry to the application.
/// <FTLDisablePartialRepaint/>
/// <true/>
void _disablePartialRepaint(String testDirectory) {
final String manifestPath = path.join(
testDirectory, 'ios', 'Runner', 'Info.plist');
final File file = File(manifestPath);

if (!file.existsSync()) {
throw Exception('Info.plist not found at $manifestPath');
}

final String xmlStr = file.readAsStringSync();
final XmlDocument xmlDoc = XmlDocument.parse(xmlStr);
final List<(String, String)> keyPairs = <(String, String)>[
('FLTDisablePartialRepaint', 'true'),
];

final XmlElement applicationNode =
xmlDoc.findAllElements('dict').first;

// Check if the meta-data node already exists.
for (final (String key, String value) in keyPairs) {
applicationNode.children.add(XmlElement(XmlName('key'), <XmlAttribute>[], <XmlNode>[
XmlText(key)
], false));
applicationNode.children.add(XmlElement(XmlName(value)));
}

file.writeAsStringSync(xmlDoc.toXmlString(pretty: true, indent: ' '));
}

Future<void> _resetPlist(String testDirectory) async {
final String manifestPath = path.join(
testDirectory, 'ios', 'Runner', 'Info.plist');
final File file = File(manifestPath);

if (!file.existsSync()) {
throw Exception('Info.plist not found at $manifestPath');
}

await exec('git', <String>['checkout', file.path]);
}

/// Opens the file at testDirectory + 'android/app/src/main/AndroidManifest.xml'
/// and adds the following entry to the application.
/// <meta-data
Expand Down Expand Up @@ -1124,6 +1170,7 @@ class PerfTest {
this.timeoutSeconds,
this.enableImpeller,
this.forceOpenGLES,
this.disablePartialRepaint = false,
}): _resultFilename = resultFilename;

const PerfTest.e2e(
Expand All @@ -1142,6 +1189,7 @@ class PerfTest {
this.timeoutSeconds,
this.enableImpeller,
this.forceOpenGLES,
this.disablePartialRepaint = false,
}) : saveTraceFile = false, timelineFileName = null, _resultFilename = resultFilename;

/// The directory where the app under test is defined.
Expand Down Expand Up @@ -1181,6 +1229,9 @@ class PerfTest {
/// Whether the perf test force Impeller's OpenGLES backend.
final bool? forceOpenGLES;

/// Whether partial repaint functionality should be disabled (iOS only).
final bool disablePartialRepaint;

/// Number of seconds to time out the test after, allowing debug callbacks to run.
final int? timeoutSeconds;

Expand Down Expand Up @@ -1230,14 +1281,42 @@ class PerfTest {
final String? localEngineHost = localEngineHostFromEnv;
final String? localEngineSrcPath = localEngineSrcPathFromEnv;

Future<void> Function()? manifestReset;
if (forceOpenGLES ?? false) {
assert(enableImpeller!);
_addOpenGLESToManifest(testDirectory);
manifestReset = () => _resetManifest(testDirectory);
bool changedPlist = false;
bool changedManifest = false;

Future<void> resetManifest() async {
if (!changedManifest) {
return;
}
try {
await _resetManifest(testDirectory);
} catch (err) {
print('Caught exception while trying to reset AndroidManifest: $err');
}
}

Future<void> resetPlist() async {
if (!changedPlist) {
return;
}
try {
await _resetPlist(testDirectory);
} catch (err) {
print('Caught exception while trying to reset Info.plist: $err');
}
}

try {
if (forceOpenGLES ?? false) {
assert(enableImpeller!);
changedManifest = true;
_addOpenGLESToManifest(testDirectory);
}
if (disablePartialRepaint) {
changedPlist = true;
_disablePartialRepaint(testDirectory);
}

final List<String> options = <String>[
if (localEngine != null) ...<String>['--local-engine', localEngine],
if (localEngineHost != null) ...<String>[
Expand Down Expand Up @@ -1278,9 +1357,8 @@ class PerfTest {
await flutter('drive', options: options);
}
} finally {
if (manifestReset != null) {
await manifestReset();
}
await resetManifest();
await resetPlist();
}

final Map<String, dynamic> data = json.decode(
Expand Down

0 comments on commit 925f3ee

Please sign in to comment.