[web] Better way to detect CanvasKit variant (flutter/engine#40154)

[web] Better way to detect CanvasKit variant
This commit is contained in:
Mouad Debbar
2023-03-15 16:35:46 -04:00
committed by GitHub
parent 720b30fd1d
commit 5799b8da8a
5 changed files with 40 additions and 63 deletions

View File

@@ -268,6 +268,4 @@ int _detectWebGLVersion() {
}
/// Whether the current browser supports the Chromium variant of CanvasKit.
const bool browserSupportsCanvaskitChromium = false;
// TODO(mdebbar): Uncomment this to enable real detection of browser support.
// final bool browserSupportsCanvaskitChromium = domIntl.v8BreakIterator != null;
final bool browserSupportsCanvaskitChromium = domIntl.v8BreakIterator != null;

View File

@@ -28,21 +28,9 @@ import 'renderer.dart';
/// Entrypoint into the CanvasKit API.
late CanvasKit canvasKit;
late CanvasKitVariant _canvasKitVariant;
/// Which variant of CanvasKit we are using.
CanvasKitVariant get canvasKitVariant => _canvasKitVariant;
set canvasKitVariant(CanvasKitVariant value) {
if (value == CanvasKitVariant.auto) {
throw ArgumentError.value(
value,
'value',
'CanvasKitVariant.auto is not a valid value for canvasKitVariant',
);
}
_canvasKitVariant = value;
}
// TODO(mdebbar): Turn this on when CanvasKit Chromium is ready.
// https://github.com/flutter/flutter/issues/122329
const bool _enableCanvasKitChromiumInAutoMode = false;
/// Sets the [CanvasKit] object on `window` so we can use `@JS()` to bind to
/// static APIs.
@@ -1884,6 +1872,13 @@ extension SkParagraphBuilderNamespaceExtension on SkParagraphBuilderNamespace {
SkParagraphStyle paragraphStyle,
TypefaceFontProvider? fontManager,
);
bool RequiresClientICU() {
if (!js_util.hasProperty(this, 'RequiresClientICU')) {
return false;
}
return js_util.callMethod(this, 'RequiresClientICU', const <Object>[],) as bool;
}
}
@JS()
@@ -2699,47 +2694,26 @@ void patchCanvasKitModule(DomHTMLScriptElement canvasKitScript) {
}
}
String get _canvasKitBaseUrl => configuration.canvasKitBaseUrl;
const String _kFullCanvasKitJsFileName = 'canvaskit.js';
const String _kChromiumCanvasKitJsFileName = 'chromium/canvaskit.js';
// TODO(mdebbar): Replace this with a Record once it's supported in Dart.
class _CanvasKitVariantUrl {
const _CanvasKitVariantUrl(this.url, this.variant)
: assert(
variant != CanvasKitVariant.auto,
'CanvasKitVariant.auto cannot have a url',
);
final String url;
final CanvasKitVariant variant;
static _CanvasKitVariantUrl chromium = _CanvasKitVariantUrl(
'$_canvasKitBaseUrl$_kChromiumCanvasKitJsFileName',
CanvasKitVariant.chromium,
);
static _CanvasKitVariantUrl full = _CanvasKitVariantUrl(
'$_canvasKitBaseUrl$_kFullCanvasKitJsFileName',
CanvasKitVariant.full,
);
}
List<_CanvasKitVariantUrl> get _canvasKitUrls {
String get _canvasKitBaseUrl => configuration.canvasKitBaseUrl;
List<String> get _canvasKitJsFileNames {
switch (configuration.canvasKitVariant) {
case CanvasKitVariant.auto:
return <_CanvasKitVariantUrl>[
if (browserSupportsCanvaskitChromium) _CanvasKitVariantUrl.chromium,
_CanvasKitVariantUrl.full,
return <String>[
if (_enableCanvasKitChromiumInAutoMode) _kChromiumCanvasKitJsFileName,
_kFullCanvasKitJsFileName,
];
case CanvasKitVariant.full:
return <_CanvasKitVariantUrl>[_CanvasKitVariantUrl.full];
return <String>[_kFullCanvasKitJsFileName];
case CanvasKitVariant.chromium:
return <_CanvasKitVariantUrl>[_CanvasKitVariantUrl.chromium];
return <String>[_kChromiumCanvasKitJsFileName];
}
}
Iterable<String> get _canvasKitJsUrls {
return _canvasKitJsFileNames.map((String filename) => '$_canvasKitBaseUrl$filename');
}
@visibleForTesting
String canvasKitWasmModuleUrl(String file, String canvasKitBase) =>
canvasKitBase + file;
@@ -2749,23 +2723,29 @@ String canvasKitWasmModuleUrl(String file, String canvasKitBase) =>
/// Downloads the CanvasKit JavaScript, then calls `CanvasKitInit` to download
/// and intialize the CanvasKit wasm.
Future<CanvasKit> downloadCanvasKit() async {
await _downloadOneOf(_canvasKitUrls);
await _downloadOneOf(_canvasKitJsUrls);
return CanvasKitInit(CanvasKitInitOptions(
final CanvasKit canvasKit = await CanvasKitInit(CanvasKitInitOptions(
locateFile: allowInterop(canvasKitWasmModuleUrl),
));
if (canvasKit.ParagraphBuilder.RequiresClientICU() && !browserSupportsCanvaskitChromium) {
throw Exception(
'The CanvasKit variant you are using only works on Chromium browsers. '
'Please use a different CanvasKit variant, or use a Chromium browser.',
);
}
return canvasKit;
}
/// Finds the first entry in [urls] that can be downloaded successfully, and
/// Finds the first URL in [urls] that can be downloaded successfully, and
/// downloads it.
///
/// If none of the URLs can be downloaded, throws an [Exception].
///
/// Also sets [canvasKitVariant] to the variant of CanvasKit that was downloaded.
Future<void> _downloadOneOf(Iterable<_CanvasKitVariantUrl> urls) async {
for (final _CanvasKitVariantUrl entry in urls) {
if (await _downloadCanvasKitJs(entry.url)) {
canvasKitVariant = entry.variant;
Future<void> _downloadOneOf(Iterable<String> urls) async {
for (final String url in urls) {
if (await _downloadCanvasKitJs(url)) {
return;
}
}

View File

@@ -984,7 +984,7 @@ class CkParagraphBuilder implements ui.ParagraphBuilder {
/// Builds the CkParagraph with the builder and deletes the builder.
SkParagraph _buildSkParagraph() {
if (canvasKitVariant == CanvasKitVariant.chromium) {
if (canvasKit.ParagraphBuilder.RequiresClientICU()) {
injectClientICU(_paragraphBuilder);
}
final SkParagraph result = _paragraphBuilder.build();

View File

@@ -7,7 +7,6 @@ import 'dart:typed_data';
import '../dom.dart';
import '../text/line_breaker.dart';
import 'canvaskit_api.dart';
import 'renderer.dart';
/// Injects required ICU data into the [builder].
///
@@ -15,7 +14,7 @@ import 'renderer.dart';
/// without ICU data.
void injectClientICU(SkParagraphBuilder builder) {
assert(
canvasKitVariant == CanvasKitVariant.chromium,
canvasKit.ParagraphBuilder.RequiresClientICU(),
'This method should only be used with the CanvasKit Chromium variant.',
);

View File

@@ -1624,7 +1624,7 @@ void _paragraphTests() {
builder.pushStyle(
canvasKit.TextStyle(SkTextStyleProperties()..halfLeading = true));
builder.pop();
if (canvasKitVariant == CanvasKitVariant.chromium) {
if (canvasKit.ParagraphBuilder.RequiresClientICU()) {
injectClientICU(builder);
}
final SkParagraph paragraph = builder.build();
@@ -1742,7 +1742,7 @@ void _paragraphTests() {
);
builder.addText('hello');
if (canvasKitVariant == CanvasKitVariant.chromium) {
if (canvasKit.ParagraphBuilder.RequiresClientICU()) {
injectClientICU(builder);
}