Unverified Commit 07b89dad authored by Jackson Gardner's avatar Jackson Gardner Committed by GitHub

Add support to the flutter tool to compile against the skwasm renderer (#124296)

Add support to the flutter tool to compile against the skwasm renderer
parent 8eb1c9d1
......@@ -284,6 +284,11 @@ class Dart2WasmTarget extends Dart2WebTarget {
dartSdkRoot,
'--libraries-spec',
artifacts.getHostArtifact(HostArtifact.flutterWebLibrariesJson).path,
if (webRenderer == WebRendererMode.skwasm)
...<String>[
'--import-shared-memory',
'--shared-memory-max-pages=32768',
],
'--depfile=${depFile.path}',
environment.buildDir.childFile('main.dart').path, // dartfile
......@@ -312,9 +317,6 @@ class Dart2WasmTarget extends Dart2WebTarget {
Source.pattern('{OUTPUT_DIR}/main.dart.wasm'),
Source.pattern('{OUTPUT_DIR}/main.dart.mjs'),
];
// TODO(jacksongardner): override `depfiles` once dart2wasm begins producing
// them: https://github.com/dart-lang/sdk/issues/50747
}
/// Unpacks the dart2js or dart2wasm compilation and resources to a given
......@@ -461,9 +463,10 @@ class WebReleaseBundle extends Target {
/// These assets can be cached until a new version of the flutter web sdk is
/// downloaded.
class WebBuiltInAssets extends Target {
const WebBuiltInAssets(this.fileSystem, {required this.isWasm});
const WebBuiltInAssets(this.fileSystem, this.webRenderer, {required this.isWasm});
final FileSystem fileSystem;
final WebRendererMode webRenderer;
final bool isWasm;
@override
......@@ -511,7 +514,9 @@ class WebBuiltInAssets extends Target {
if (isWasm) {
final File bootstrapFile = environment.outputDir.childFile('main.dart.js');
bootstrapFile.writeAsStringSync(wasm_bootstrap.generateWasmBootstrapFile());
bootstrapFile.writeAsStringSync(
wasm_bootstrap.generateWasmBootstrapFile(webRenderer == WebRendererMode.skwasm)
);
}
// Write the flutter.js file
......@@ -538,7 +543,7 @@ class WebServiceWorker extends Target {
List<Target> get dependencies => <Target>[
if (isWasm) Dart2WasmTarget(webRenderer) else Dart2JSTarget(webRenderer),
WebReleaseBundle(webRenderer, isWasm: isWasm),
WebBuiltInAssets(fileSystem, isWasm: isWasm),
WebBuiltInAssets(fileSystem, webRenderer, isWasm: isWasm),
];
@override
......
......@@ -183,6 +183,7 @@ class BuildWebCommand extends BuildSubCommand {
displayNullSafetyMode(buildInfo);
final WebBuilder webBuilder = WebBuilder(
logger: globals.logger,
processManager: globals.processManager,
buildSystem: globals.buildSystem,
fileSystem: globals.fs,
flutterVersion: globals.flutterVersion,
......
......@@ -316,6 +316,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
} else {
final WebBuilder webBuilder = WebBuilder(
logger: _logger,
processManager: globals.processManager,
buildSystem: globals.buildSystem,
fileSystem: _fileSystem,
flutterVersion: globals.flutterVersion,
......@@ -393,6 +394,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
try {
final WebBuilder webBuilder = WebBuilder(
logger: _logger,
processManager: globals.processManager,
buildSystem: globals.buildSystem,
fileSystem: _fileSystem,
flutterVersion: globals.flutterVersion,
......
......@@ -163,6 +163,7 @@ abstract class FlutterCommand extends Command<void> {
'auto': WebRendererMode.autoDetect,
'canvaskit': WebRendererMode.canvaskit,
'html': WebRendererMode.html,
'skwasm': WebRendererMode.skwasm,
};
/// The map used to convert web renderer mode to a List of dart-defines.
......@@ -179,6 +180,11 @@ abstract class FlutterCommand extends Command<void> {
'FLUTTER_WEB_AUTO_DETECT=false',
'FLUTTER_WEB_USE_SKIA=false',
],
WebRendererMode.skwasm: <String>[
'FLUTTER_WEB_AUTO_DETECT=false',
'FLUTTER_WEB_USE_SKIA=false',
'FLUTTER_WEB_USE_SKWASM=true',
]
};
@override
......@@ -663,12 +669,13 @@ abstract class FlutterCommand extends Command<void> {
argParser.addOption(
FlutterOptions.kWebRendererFlag,
defaultsTo: 'auto',
allowed: <String>['auto', 'canvaskit', 'html'],
allowed: <String>['auto', 'canvaskit', 'html', 'skwasm'],
help: 'The renderer implementation to use when building for the web.',
allowedHelp: <String, String>{
'html': 'Always use the HTML renderer. This renderer uses a combination of HTML, CSS, SVG, 2D Canvas, and WebGL.',
'canvaskit': 'Always use the CanvasKit renderer. This renderer uses WebGL and WebAssembly to render graphics.',
'auto': 'Use the HTML renderer on mobile devices, and CanvasKit on desktop devices.',
'skwasm': 'Always use the experimental skwasm renderer.',
}
);
}
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:process/process.dart';
import '../artifacts.dart';
import '../base/common.dart';
import '../base/file_system.dart';
......@@ -26,17 +28,20 @@ export 'compiler_config.dart';
class WebBuilder {
WebBuilder({
required Logger logger,
required ProcessManager processManager,
required BuildSystem buildSystem,
required Usage usage,
required FlutterVersion flutterVersion,
required FileSystem fileSystem,
}) : _logger = logger,
_processManager = processManager,
_buildSystem = buildSystem,
_flutterUsage = usage,
_flutterVersion = flutterVersion,
_fileSystem = fileSystem;
final Logger _logger;
final ProcessManager _processManager;
final BuildSystem _buildSystem;
final Usage _flutterUsage;
final FlutterVersion _flutterVersion;
......@@ -95,7 +100,7 @@ class WebBuilder {
artifacts: globals.artifacts!,
fileSystem: _fileSystem,
logger: _logger,
processManager: globals.processManager,
processManager: _processManager,
platform: globals.platform,
usage: _flutterUsage,
cacheDir: globals.cache.getRoot(),
......@@ -135,6 +140,8 @@ enum WebRendererMode {
canvaskit,
/// Always uses html.
html,
/// Always use skwasm.
skwasm,
}
/// The correct precompiled artifact to use for each build and render mode.
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
String generateWasmBootstrapFile() {
return r'''
String generateWasmBootstrapFile(bool isSkwasm) {
return '''
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -12,20 +12,46 @@ String generateWasmBootstrapFile() {
let dart2wasm_runtime;
let moduleInstance;
try {
const dartModulePromise = WebAssembly.compileStreaming(fetch("main.dart.wasm"));
const dartModulePromise = WebAssembly.compileStreaming(fetch('main.dart.wasm'));
${generateImports(isSkwasm)}
dart2wasm_runtime = await import('./main.dart.mjs');
moduleInstance = await dart2wasm_runtime.instantiate(dartModulePromise, {});
moduleInstance = await dart2wasm_runtime.instantiate(dartModulePromise, imports);
} catch (exception) {
console.error(`Failed to fetch and instantiate wasm module: ${exception}`);
console.error(`Failed to fetch and instantiate wasm module: \${exception}`);
}
if (moduleInstance) {
try {
await dart2wasm_runtime.invoke(moduleInstance);
} catch (exception) {
console.error(`Exception while invoking test: ${exception}`);
console.error(`Exception while invoking test: \${exception}`);
}
}
})();
''';
}
String generateImports(bool isSkwasm) {
if (isSkwasm) {
return r'''
const imports = new Promise((resolve, reject) => {
const skwasmScript = document.createElement('script');
skwasmScript.src = 'canvaskit/skwasm.js';
document.body.appendChild(skwasmScript);
skwasmScript.addEventListener('load', async () => {
const skwasmInstance = await skwasm();
window._flutter_skwasmInstance = skwasmInstance;
resolve({
'skwasm': skwasmInstance.asm,
'ffi': {
'memory': skwasmInstance.wasmMemory,
}
});
});
});
''';
} else {
return ' const imports = {};';
}
}
......@@ -810,6 +810,40 @@ void main() {
ProcessManager: () => processManager,
}));
test('Dart2WasmTarget with skwasm renderer adds extra flags', () => testbed.run(() async {
environment.defines[kBuildMode] = 'release';
final File depFile = environment.buildDir.childFile('dart2wasm.d');
processManager.addCommand(FakeCommand(
command: <String>[
'bin/cache/dart-sdk/bin/dartaotruntime',
'--disable-dart-dev',
'bin/cache/dart-sdk/bin/snapshots/dart2wasm_product.snapshot',
'-Ddart.vm.product=true',
'--packages=.dart_tool/package_config.json',
'--dart-sdk=bin/cache/dart-sdk',
'--multi-root-scheme',
'org-dartlang-sdk',
'--multi-root',
'bin/cache/flutter_web_sdk',
'--multi-root',
'bin/cache',
'--libraries-spec',
'bin/cache/flutter_web_sdk/libraries.json',
'--import-shared-memory',
'--shared-memory-max-pages=32768',
'--depfile=${depFile.absolute.path}',
environment.buildDir.childFile('main.dart').absolute.path,
environment.buildDir.childFile('main.dart.wasm').absolute.path,
])
);
await Dart2WasmTarget(WebRendererMode.skwasm).build(environment);
}, overrides: <Type, Generator>{
ProcessManager: () => processManager,
}));
test('Generated service worker is empty with none-strategy', () => testbed.run(() {
final String fileGeneratorsPath =
environment.artifacts.getArtifactPath(Artifact.flutterToolsFileGenerators);
......@@ -922,7 +956,7 @@ void main() {
..createSync(recursive: true)
..writeAsStringSync('OL');
await WebBuiltInAssets(globals.fs, isWasm: false).build(environment);
await WebBuiltInAssets(globals.fs, WebRendererMode.autoDetect, isWasm: false).build(environment);
// No caching of source maps.
final String fileGeneratorsPath = environment.artifacts
......@@ -939,7 +973,7 @@ void main() {
globals.fs.file('bin/cache/flutter_web_sdk/canvaskit/canvaskit.wasm')
.createSync(recursive: true);
await WebBuiltInAssets(globals.fs, isWasm: true).build(environment);
await WebBuiltInAssets(globals.fs, WebRendererMode.autoDetect, isWasm: true).build(environment);
expect(environment.outputDir.childFile('main.dart.js').existsSync(), true);
expect(environment.outputDir.childDirectory('canvaskit')
......@@ -952,7 +986,7 @@ void main() {
..createSync(recursive: true);
canvasKitInput.writeAsStringSync('foo', flush: true);
await WebBuiltInAssets(globals.fs, isWasm: true).build(environment);
await WebBuiltInAssets(globals.fs, WebRendererMode.autoDetect, isWasm: true).build(environment);
final File canvasKitOutputBefore = environment.outputDir.childDirectory('canvaskit')
.childFile('canvaskit.wasm');
......@@ -961,7 +995,7 @@ void main() {
canvasKitInput.writeAsStringSync('bar', flush: true);
await WebBuiltInAssets(globals.fs, isWasm: true).build(environment);
await WebBuiltInAssets(globals.fs, WebRendererMode.autoDetect, isWasm: true).build(environment);
final File canvasKitOutputAfter = environment.outputDir.childDirectory('canvaskit')
.childFile('canvaskit.wasm');
......
......@@ -57,6 +57,7 @@ void main() {
final WebBuilder webBuilder = WebBuilder(
logger: logger,
processManager: FakeProcessManager.any(),
buildSystem: buildSystem,
usage: testUsage,
flutterVersion: flutterVersion,
......@@ -95,6 +96,7 @@ void main() {
final WebBuilder webBuilder = WebBuilder(
logger: logger,
processManager: FakeProcessManager.any(),
buildSystem: buildSystem,
usage: testUsage,
flutterVersion: flutterVersion,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment