Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions lib/web_ui/lib/src/engine/canvaskit/initialization.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,40 @@
// @dart = 2.10
part of engine;

/// EXPERIMENTAL: Enable the Skia-based rendering backend.
const bool experimentalUseSkia =
/// A JavaScript entrypoint that allows developer to set rendering backend
/// at runtime before launching the application.
@JS('window.flutterWebRenderer')
external String? get requestedRendererType;

/// Whether to use CanvasKit as the rendering backend.
bool get useCanvasKit =>
_autoDetect ? _detectRenderer() : _useSkia;

/// Returns true if CanvasKit is used.
///
/// Otherwise, returns false.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bool _detectRenderer() {
if (requestedRendererType != null) {
return requestedRendererType! == 'canvaskit';
}
// If requestedRendererType is not specified, use CanvasKit for desktop and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yjbanov @ferhatb if I'm not mistaken we are setting Canvaskit as default for desktop. I am personally not sure if we are ready for this step as testing goes:

  • Majority of our unit tests are build with canvaskit.
  • We have coverage in many critical areas with integration tests on Desktop browsers (text editing, font loading, keyboard, platform selection, image loading, semantics (in draft), scroll (in pr), pointer events (in pr), tree shaking, platform messages). None of them runs with Canvaskit though.

Shall we prioritize running them with Canvaskit then?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. We should definitely ramp up testing in CanvasKit mode. This PR is not changing the default yet (--web-renderer=auto will default to CanvasKit on desktop, but --web-renderer itself defaults to html so overall the defaults are not changing), so tests can proceed on their own schedule.

In terms of test prioritization, testing things in CanvasKit mode where the choice of renderer has known effects is a good place to start from. From your list the affected areas are: font loading, image loading. Text editing is also affected but I'm not sure our existing tests will catch the distinction, so we may need new tests. Tree shaking is affected; we use devicelab for that, so it would be best to reuse the existing tests. Other things affected by renderer choice: rendering quality, platform views. There's also performance, but our benchmarks already cover both HTML and CanvasKit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@angjieli tl;dr there's no action items for this PR w.r.t. running existing tests in CanvasKit mode

// html for mobile.
return isDesktop;
}

/// Auto detect which rendering backend to use.
///
/// Using flutter tools option "--web-render=auto" would set the value to true.
/// Otherwise, it would be false.
const bool _autoDetect =
bool.fromEnvironment('FLUTTER_WEB_AUTO_DETECT', defaultValue: false);

/// Enable the Skia-based rendering backend.
///
/// Using flutter tools option "--web-render=canvaskit" would set the value to
/// true.
/// Using flutter tools option "--web-render=html" would set the value to false.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nit: typo for canvaskit

const bool _useSkia =
bool.fromEnvironment('FLUTTER_WEB_USE_SKIA', defaultValue: false);

// If set to true, forces CPU-only rendering (i.e. no WebGL).
Expand Down
6 changes: 3 additions & 3 deletions lib/web_ui/lib/src/engine/canvaskit/shader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class CkGradientLinear extends CkShader implements ui.Gradient {

@override
SkShader createDefault() {
assert(experimentalUseSkia);
assert(useCanvasKit);

return canvasKit.SkShader.MakeLinearGradient(
toSkPoint(from),
Expand Down Expand Up @@ -109,7 +109,7 @@ class CkGradientRadial extends CkShader implements ui.Gradient {

@override
SkShader createDefault() {
assert(experimentalUseSkia);
assert(useCanvasKit);

return canvasKit.SkShader.MakeRadialGradient(
toSkPoint(center),
Expand Down Expand Up @@ -141,7 +141,7 @@ class CkGradientConical extends CkShader implements ui.Gradient {

@override
SkShader createDefault() {
assert(experimentalUseSkia);
assert(useCanvasKit);
return canvasKit.SkShader.MakeTwoPointConicalGradient(
toSkPoint(focal),
focalRadius,
Expand Down
4 changes: 2 additions & 2 deletions lib/web_ui/lib/src/engine/dom_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class DomRenderer {
html.MetaElement? _viewportMeta;

/// The canvaskit script, downloaded from a CDN. Only created if
/// [experimentalUseSkia] is set to true.
/// [useCanvasKit] is set to true.
html.ScriptElement? get canvasKitScript => _canvasKitScript;
html.ScriptElement? _canvasKitScript;

Expand Down Expand Up @@ -451,7 +451,7 @@ flt-glass-pane * {
});
}

if (experimentalUseSkia) {
if (useCanvasKit) {
_canvasKitScript?.remove();
_canvasKitScript = html.ScriptElement();
_canvasKitScript!.src = canvasKitBaseUrl + 'canvaskit.js';
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/html/shaders/shader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ class GradientRadial extends EngineGradient {
@override
Object createPaintStyle(html.CanvasRenderingContext2D? ctx,
ui.Rect? shaderBounds) {
if (!experimentalUseSkia) {
if (!useCanvasKit) {
if (tileMode != ui.TileMode.clamp) {
throw UnimplementedError(
'TileMode not supported in GradientRadial shader');
Expand Down
6 changes: 3 additions & 3 deletions lib/web_ui/lib/src/engine/platform_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
return;

case 'flutter/platform_views':
if (experimentalUseSkia) {
if (useCanvasKit) {
rasterizer!.surface.viewEmbedder
.handlePlatformViewCall(data, callback);
} else {
Expand Down Expand Up @@ -482,7 +482,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
/// painting.
@override
void render(ui.Scene scene, [ui.FlutterView? view]) {
if (experimentalUseSkia) {
if (useCanvasKit) {
// "Build finish" and "raster start" happen back-to-back because we
// render on the same thread, so there's no overhead from hopping to
// another thread.
Expand Down Expand Up @@ -839,7 +839,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {

@visibleForTesting
late Rasterizer? rasterizer =
experimentalUseSkia ? Rasterizer(Surface(HtmlViewEmbedder())) : null;
useCanvasKit ? Rasterizer(Surface(HtmlViewEmbedder())) : null;

/// In Flutter, platform messages are exchanged between threads so the
/// messages and responses have to be exchanged asynchronously. We simulate
Expand Down
8 changes: 4 additions & 4 deletions lib/web_ui/lib/src/ui/canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class Vertices {
List<Color>? colors,
List<int>? indices,
}) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CkVertices(
mode,
positions,
Expand All @@ -53,7 +53,7 @@ class Vertices {
Int32List? colors,
Uint16List? indices,
}) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CkVertices.raw(
mode,
positions,
Expand All @@ -73,7 +73,7 @@ class Vertices {

abstract class PictureRecorder {
factory PictureRecorder() {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CkPictureRecorder();
} else {
return engine.EnginePictureRecorder();
Expand All @@ -85,7 +85,7 @@ abstract class PictureRecorder {

abstract class Canvas {
factory Canvas(PictureRecorder recorder, [Rect? cullRect]) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CanvasKitCanvas(recorder, cullRect);
} else {
return engine.SurfaceCanvas(recorder as engine.EnginePictureRecorder, cullRect);
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/ui/compositing.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ abstract class PhysicalShapeEngineLayer implements EngineLayer {}

abstract class SceneBuilder {
factory SceneBuilder() {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.LayerSceneBuilder();
} else {
return engine.SurfaceSceneBuilder();
Expand Down
10 changes: 5 additions & 5 deletions lib/web_ui/lib/src/ui/initialization.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ Future<void> _initializePlatform({

// This needs to be after `webOnlyInitializeEngine` because that is where the
// canvaskit script is added to the page.
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
await engine.initializeCanvasKit();
}

assetManager ??= const engine.AssetManager();
await webOnlySetAssetManager(assetManager);
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
await engine.skiaFontCollection.ensureFontsLoaded();
} else {
await _fontCollection!.ensureFontsLoaded();
Expand All @@ -54,22 +54,22 @@ Future<void> webOnlySetAssetManager(engine.AssetManager assetManager) async {

_assetManager = assetManager;

if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
engine.ensureSkiaFontCollectionInitialized();
} else {
_fontCollection ??= engine.FontCollection();
_fontCollection!.clear();
}

if (_assetManager != null) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
await engine.skiaFontCollection.registerFonts(_assetManager!);
} else {
await _fontCollection!.registerFonts(_assetManager!);
}
}

if (debugEmulateFlutterTesterEnvironment && !engine.experimentalUseSkia) {
if (debugEmulateFlutterTesterEnvironment && !engine.useCanvasKit) {
_fontCollection!.debugRegisterTestFonts();
}
}
Expand Down
20 changes: 10 additions & 10 deletions lib/web_ui/lib/src/ui/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ enum Clip {
}

abstract class Paint {
factory Paint() => engine.experimentalUseSkia ? engine.CkPaint() : engine.SurfacePaint();
factory Paint() => engine.useCanvasKit ? engine.CkPaint() : engine.SurfacePaint();
static bool enableDithering = false;
BlendMode get blendMode;
set blendMode(BlendMode value);
Expand Down Expand Up @@ -278,7 +278,7 @@ abstract class Gradient extends Shader {
List<double>? colorStops,
TileMode tileMode = TileMode.clamp,
Float64List? matrix4,
]) => engine.experimentalUseSkia
]) => engine.useCanvasKit
? engine.CkGradientLinear(from, to, colors, colorStops, tileMode, matrix4)
: engine.GradientLinear(from, to, colors, colorStops, tileMode, matrix4);
factory Gradient.radial(
Expand All @@ -296,13 +296,13 @@ abstract class Gradient extends Shader {
// If focal == center and the focal radius is 0.0, it's still a regular radial gradient
final Float32List? matrix32 = matrix4 != null ? engine.toMatrix32(matrix4) : null;
if (focal == null || (focal == center && focalRadius == 0.0)) {
return engine.experimentalUseSkia
return engine.useCanvasKit
? engine.CkGradientRadial(center, radius, colors, colorStops, tileMode, matrix32)
: engine.GradientRadial(center, radius, colors, colorStops, tileMode, matrix32);
} else {
assert(center != Offset.zero ||
focal != Offset.zero); // will result in exception(s) in Skia side
return engine.experimentalUseSkia
return engine.useCanvasKit
? engine.CkGradientConical(
focal, focalRadius, center, radius, colors, colorStops, tileMode, matrix32)
: engine.GradientConical(
Expand All @@ -317,7 +317,7 @@ abstract class Gradient extends Shader {
double startAngle = 0.0,
double endAngle = math.pi * 2,
Float64List? matrix4,
]) => engine.experimentalUseSkia
]) => engine.useCanvasKit
? engine.CkGradientSweep(center, colors, colorStops, tileMode, startAngle,
endAngle, matrix4 != null ? engine.toMatrix32(matrix4) : null)
: engine.GradientSweep(center, colors, colorStops, tileMode, startAngle,
Expand Down Expand Up @@ -393,7 +393,7 @@ enum FilterQuality {

class ImageFilter {
factory ImageFilter.blur({double sigmaX = 0.0, double sigmaY = 0.0}) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CkImageFilter.blur(sigmaX: sigmaX, sigmaY: sigmaY);
}
return engine.EngineImageFilter.blur(sigmaX: sigmaX, sigmaY: sigmaY);
Expand Down Expand Up @@ -451,7 +451,7 @@ Future<Codec> instantiateImageCodec(
}

String? _instantiateImageCodec(Uint8List list, engine.Callback<Codec> callback) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
engine.skiaInstantiateImageCodec(list, callback);
return null;
}
Expand All @@ -471,7 +471,7 @@ String? _instantiateImageCodecFromUrl(
engine.WebOnlyImageCodecChunkCallback? chunkCallback,
engine.Callback<Codec> callback,
) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
engine.skiaInstantiateWebImageCodec(uri.toString(), callback, chunkCallback);
return null;
} else {
Expand Down Expand Up @@ -576,7 +576,7 @@ void decodeImageFromPixels(
int? targetHeight,
bool allowUpscaling = true,
}) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
engine.skiaInstantiateImageCodec(
pixels,
(Codec codec) {
Expand Down Expand Up @@ -695,7 +695,7 @@ class Shadow {

class ImageShader extends Shader {
factory ImageShader(Image image, TileMode tmx, TileMode tmy, Float64List matrix4) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CkImageShader(image, tmx, tmy, matrix4);
}
throw UnsupportedError('ImageShader not implemented for web platform.');
Expand Down
6 changes: 3 additions & 3 deletions lib/web_ui/lib/src/ui/path.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ part of ui;

abstract class Path {
factory Path() {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CkPath();
} else {
return engine.SurfacePath();
}
}
factory Path.from(Path source) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CkPath.from(source as engine.CkPath);
} else {
return engine.SurfacePath.from(source as engine.SurfacePath);
Expand Down Expand Up @@ -64,7 +64,7 @@ abstract class Path {
static Path combine(PathOperation operation, Path path1, Path path2) {
assert(path1 != null); // ignore: unnecessary_null_comparison
assert(path2 != null); // ignore: unnecessary_null_comparison
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CkPath.combine(operation, path1, path2);
}
throw UnimplementedError();
Expand Down
8 changes: 4 additions & 4 deletions lib/web_ui/lib/src/ui/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ abstract class TextStyle {
List<Shadow>? shadows,
List<FontFeature>? fontFeatures,
}) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CkTextStyle(
color: color,
decoration: decoration,
Expand Down Expand Up @@ -318,7 +318,7 @@ abstract class ParagraphStyle {
String? ellipsis,
Locale? locale,
}) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CkParagraphStyle(
textAlign: textAlign,
textDirection: textDirection,
Expand Down Expand Up @@ -585,7 +585,7 @@ abstract class Paragraph {

abstract class ParagraphBuilder {
factory ParagraphBuilder(ParagraphStyle style) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.CkParagraphBuilder(style);
} else {
return engine.EngineParagraphBuilder(style as engine.EngineParagraphStyle);
Expand All @@ -608,7 +608,7 @@ abstract class ParagraphBuilder {
}

Future<void> loadFontFromList(Uint8List list, {String? fontFamily}) {
if (engine.experimentalUseSkia) {
if (engine.useCanvasKit) {
return engine.skiaFontCollection.loadFontFromList(list, fontFamily: fontFamily).then(
(_) => engine.sendFontChangeMessage()
);
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/test/canvaskit/canvaskit_api_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void testMain() {
});

test('Using CanvasKit', () {
expect(experimentalUseSkia, true);
expect(useCanvasKit, true);
});

_blendModeTests();
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/test/canvaskit/frame_timings_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ void testMain() {
});

test('Using CanvasKit', () {
expect(experimentalUseSkia, true);
expect(useCanvasKit, true);
});

test('collects frame timings', () async {
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/test/canvaskit/path_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ void testMain() {
});

test('Using CanvasKit', () {
expect(experimentalUseSkia, true);
expect(useCanvasKit, true);
});

test(CkPathMetrics, () {
Expand Down
Loading