From c7d2afd355487a8703720510d4ef094a9bae23ed Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Tue, 5 Oct 2021 14:38:46 -0700 Subject: [PATCH] Roll CanvasKit to 0.30 (flutter/engine#28965) --- DEPS | 2 +- .../lib/web_ui/dev/canvaskit_lock.yaml | 2 +- .../src/engine/canvaskit/canvaskit_api.dart | 75 ++++++++++++------- .../src/engine/canvaskit/image_filter.dart | 17 +++-- .../src/engine/canvaskit/initialization.dart | 2 +- .../lib/src/engine/canvaskit/surface.dart | 11 --- .../test/canvaskit/canvaskit_api_test.dart | 58 +++++++------- 7 files changed, 89 insertions(+), 78 deletions(-) diff --git a/DEPS b/DEPS index eee89fd78d7..5fe5e098577 100644 --- a/DEPS +++ b/DEPS @@ -31,7 +31,7 @@ vars = { # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. - 'canvaskit_cipd_instance': 'srPdrAoUIWOde-KMPE5S8koi64mejhae7NzvfR_7m3gC', + 'canvaskit_cipd_instance': '1e8cK_8LOs0dz4lqd20LwTUYNqfu_4YL-dFG5yK1xXQC', # When updating the Dart revision, ensure that all entries that are # dependencies of Dart are also updated to match the entries in the diff --git a/engine/src/flutter/lib/web_ui/dev/canvaskit_lock.yaml b/engine/src/flutter/lib/web_ui/dev/canvaskit_lock.yaml index 78813b4e0fb..79d8bdbc598 100644 --- a/engine/src/flutter/lib/web_ui/dev/canvaskit_lock.yaml +++ b/engine/src/flutter/lib/web_ui/dev/canvaskit_lock.yaml @@ -1,4 +1,4 @@ # Specifies the version of CanvasKit to use for Flutter Web apps. # # See `lib/web_ui/README.md` for how to update this file. -canvaskit_version: "0.28.1" +canvaskit_version: "0.30.0" diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart index 0a46aa9e4f0..7b8a93eb7f1 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart @@ -46,7 +46,6 @@ class CanvasKit { external SkPaintStyleEnum get PaintStyle; external SkStrokeCapEnum get StrokeCap; external SkStrokeJoinEnum get StrokeJoin; - external SkFilterQualityEnum get FilterQuality; external SkBlurStyleEnum get BlurStyle; external SkTileModeEnum get TileMode; external SkFilterModeEnum get FilterMode; @@ -115,7 +114,6 @@ class CanvasKit { ColorSpace colorSpace, ); external SkSurface MakeSWCanvasSurface(html.CanvasElement canvas); - external void setCurrentContext(int glContext); /// Creates an image from decoded pixels represented as a list of bytes. /// @@ -659,30 +657,6 @@ SkStrokeJoin toSkStrokeJoin(ui.StrokeJoin strokeJoin) { return _skStrokeJoins[strokeJoin.index]; } -@JS() -class SkFilterQualityEnum { - external SkFilterQuality get None; - external SkFilterQuality get Low; - external SkFilterQuality get Medium; - external SkFilterQuality get High; -} - -@JS() -class SkFilterQuality { - external int get value; -} - -final List _skFilterQualitys = [ - canvasKit.FilterQuality.None, - canvasKit.FilterQuality.Low, - canvasKit.FilterQuality.Medium, - canvasKit.FilterQuality.High, -]; - -SkFilterQuality toSkFilterQuality(ui.FilterQuality filterQuality) { - return _skFilterQualitys[filterQuality.index]; -} - @JS() class SkTileModeEnum { external SkTileMode get Clamp; @@ -902,6 +876,53 @@ class SkPaint { external void delete(); } +@JS() +@anonymous +abstract class CkFilterOptions {} + +@JS() +@anonymous +class _CkCubicFilterOptions extends CkFilterOptions { + external double get B; + external double get C; + + external factory _CkCubicFilterOptions({double B, double C}); +} + +@JS() +@anonymous +class _CkTransformFilterOptions extends CkFilterOptions { + external SkFilterMode get filter; + external SkMipmapMode get mipmap; + + external factory _CkTransformFilterOptions( + {SkFilterMode filter, SkMipmapMode mipmap}); +} + +final Map _filterOptions = + { + ui.FilterQuality.none: _CkTransformFilterOptions( + filter: canvasKit.FilterMode.Nearest, + mipmap: canvasKit.MipmapMode.None, + ), + ui.FilterQuality.low: _CkTransformFilterOptions( + filter: canvasKit.FilterMode.Linear, + mipmap: canvasKit.MipmapMode.None, + ), + ui.FilterQuality.medium: _CkTransformFilterOptions( + filter: canvasKit.FilterMode.Linear, + mipmap: canvasKit.MipmapMode.Linear, + ), + ui.FilterQuality.high: _CkCubicFilterOptions( + B: 1.0 / 3, + C: 1.0 / 3, + ), +}; + +CkFilterOptions toSkFilterOptions(ui.FilterQuality filterQuality) { + return _filterOptions[filterQuality]!; +} + @JS() @anonymous class SkMaskFilter { @@ -936,7 +957,7 @@ class SkImageFilterNamespace { external SkImageFilter MakeMatrixTransform( Float32List matrix, // 3x3 matrix - SkFilterQuality filterQuality, + CkFilterOptions filterOptions, void input, // we don't use this yet ); diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/image_filter.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/image_filter.dart index 4b48c28f436..dc74021b69f 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/image_filter.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/image_filter.dart @@ -18,8 +18,7 @@ import 'skia_object_cache.dart'; /// whenever possible. /// /// Currently implemented by [CkImageFilter] and [CkColorFilter]. -abstract class CkManagedSkImageFilterConvertible - implements ui.ImageFilter { +abstract class CkManagedSkImageFilterConvertible implements ui.ImageFilter { ManagedSkiaObject get imageFilter; } @@ -134,7 +133,8 @@ class _CkBlurImageFilter extends CkImageFilter { } class _CkMatrixImageFilter extends CkImageFilter { - _CkMatrixImageFilter({ required Float64List matrix, required this.filterQuality }) + _CkMatrixImageFilter( + {required Float64List matrix, required this.filterQuality}) : this.matrix = Float64List.fromList(matrix), // ignore: unnecessary_this super._(); @@ -145,18 +145,19 @@ class _CkMatrixImageFilter extends CkImageFilter { SkImageFilter _initSkiaObject() { return canvasKit.ImageFilter.MakeMatrixTransform( toSkMatrixFromFloat64(matrix), - toSkFilterQuality(filterQuality), + toSkFilterOptions(filterQuality), null, ); } @override bool operator ==(Object other) { - if (other.runtimeType != runtimeType) + if (other.runtimeType != runtimeType) { return false; - return other is _CkMatrixImageFilter - && other.filterQuality == filterQuality - && listEquals(other.matrix, matrix); + } + return other is _CkMatrixImageFilter && + other.filterQuality == filterQuality && + listEquals(other.matrix, matrix); } @override diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/initialization.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/initialization.dart index 351c9ea0c0c..4c6fc6a13a4 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/initialization.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/initialization.dart @@ -62,7 +62,7 @@ const bool canvasKitForceCpuOnly = bool.fromEnvironment( /// The version of CanvasKit used by the web engine by default. // DO NOT EDIT THE NEXT LINE OF CODE MANUALLY // See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. -const String canvaskitVersion = '0.28.1'; +const String canvaskitVersion = '0.30.0'; /// The URL to use when downloading the CanvasKit script and associated wasm. /// diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/surface.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/surface.dart index 4713bdfaad7..4a3a2ac5bd8 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/surface.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/surface.dart @@ -114,9 +114,6 @@ class Surface { SurfaceFrame acquireFrame(ui.Size size) { final CkSurface surface = createOrUpdateSurfaces(size); - if (surface.context != null) { - canvasKit.setCurrentContext(surface.context!); - } // ignore: prefer_function_declarations_over_variables final SubmitCallback submitCallback = (SurfaceFrame surfaceFrame, CkCanvas canvas) { @@ -171,10 +168,6 @@ class Surface { // new canvas larger than required to avoid many canvas creations. final ui.Size newSize = previousCanvasSize == null ? size : size * 1.4; - // Only resources from the current context can be disposed. - if (_glContext != null && _glContext != 0) { - canvasKit.setCurrentContext(_glContext!); - } _surface?.dispose(); _surface = null; _addedToScene = false; @@ -342,7 +335,6 @@ class Surface { return _makeSoftwareCanvasSurface( htmlCanvas!, 'Failed to initialize WebGL context'); } else { - canvasKit.setCurrentContext(_glContext!); final SkSurface? skSurface = canvasKit.MakeOnScreenGLSurface( _grContext!, size.width.ceil(), @@ -374,9 +366,6 @@ class Surface { } bool _presentSurface() { - if (_surface!.context != null) { - canvasKit.setCurrentContext(_surface!.context!); - } _surface!.flush(); return true; } diff --git a/engine/src/flutter/lib/web_ui/test/canvaskit/canvaskit_api_test.dart b/engine/src/flutter/lib/web_ui/test/canvaskit/canvaskit_api_test.dart index 8001581b1e5..e42cbd41fb3 100644 --- a/engine/src/flutter/lib/web_ui/test/canvaskit/canvaskit_api_test.dart +++ b/engine/src/flutter/lib/web_ui/test/canvaskit/canvaskit_api_test.dart @@ -27,7 +27,6 @@ void testMain() { _paintStyleTests(); _strokeCapTests(); _strokeJoinTests(); - _filterQualityTests(); _blurStyleTests(); _tileModeTests(); _fillTypeTests(); @@ -145,21 +144,6 @@ void _strokeJoinTests() { }); } -void _filterQualityTests() { - test('filter quality mapping is correct', () { - expect(canvasKit.FilterQuality.None.value, ui.FilterQuality.none.index); - expect(canvasKit.FilterQuality.Low.value, ui.FilterQuality.low.index); - expect(canvasKit.FilterQuality.Medium.value, ui.FilterQuality.medium.index); - expect(canvasKit.FilterQuality.High.value, ui.FilterQuality.high.index); - }); - - test('ui.FilterQuality converts to SkFilterQuality', () { - for (final ui.FilterQuality cap in ui.FilterQuality.values) { - expect(toSkFilterQuality(cap).value, cap.index); - } - }); -} - void _blurStyleTests() { test('blur style mapping is correct', () { expect(canvasKit.BlurStyle.Normal.value, ui.BlurStyle.normal.index); @@ -418,7 +402,8 @@ void _maskFilterTests() { }); test('MaskFilter.MakeBlur with NaN sigma returns null', () { expect( - canvasKit.MaskFilter.MakeBlur(canvasKit.BlurStyle.Normal, double.nan, false), + canvasKit.MaskFilter.MakeBlur( + canvasKit.BlurStyle.Normal, double.nan, false), isNull); }); } @@ -466,11 +451,17 @@ void _imageFilterTests() { ); }); + test('toSkFilterOptions', () { + for (final ui.FilterQuality filterQuality in ui.FilterQuality.values) { + expect(toSkFilterOptions(filterQuality), isNotNull); + } + }); + test('MakeMatrixTransform', () { expect( canvasKit.ImageFilter.MakeMatrixTransform( toSkMatrixFromFloat32(Matrix4.identity().storage), - canvasKit.FilterQuality.Medium, + toSkFilterOptions(ui.FilterQuality.medium), null, ), isNotNull, @@ -627,7 +618,8 @@ typedef CanvasCallback = void Function(ui.Canvas canvas); Future toImage(CanvasCallback callback, int width, int height) { final ui.PictureRecorder recorder = ui.PictureRecorder(); - final ui.Canvas canvas = ui.Canvas(recorder, ui.Rect.fromLTRB(0, 0, width.toDouble(), height.toDouble())); + final ui.Canvas canvas = ui.Canvas( + recorder, ui.Rect.fromLTRB(0, 0, width.toDouble(), height.toDouble())); callback(canvas); final ui.Picture picture = recorder.endRecording(); return picture.toImage(width, height); @@ -639,7 +631,8 @@ Future fuzzyCompareImages(ui.Image golden, ui.Image img) async { if (golden.width != img.width || golden.height != img.height) { return false; } - int getPixel(ByteData data, int x, int y) => data.getUint32((x + y * golden.width) * 4); + int getPixel(ByteData data, int x, int y) => + data.getUint32((x + y * golden.width) * 4); final ByteData goldenData = (await golden.toByteData())!; final ByteData imgData = (await img.toByteData())!; for (int y = 0; y < golden.height; y++) { @@ -654,8 +647,8 @@ Future fuzzyCompareImages(ui.Image golden, ui.Image img) async { void _matrix4x4CompositionTests() { test('compose4x4MatrixInCanvas', () async { - const double rotateAroundX = pi / 6; // 30 degrees - const double rotateAroundY = pi / 9; // 20 degrees + const double rotateAroundX = pi / 6; // 30 degrees + const double rotateAroundY = pi / 9; // 20 degrees const int width = 150; const int height = 150; const ui.Color black = ui.Color.fromARGB(255, 0, 0, 0); @@ -666,9 +659,14 @@ void _matrix4x4CompositionTests() { const double width3 = width / 3.0; const double width5 = width / 5.0; const double width10 = width / 10.0; - canvas.drawRect(const ui.Rect.fromLTRB(-width3, -width3, width3, width3), ui.Paint()..color = green); - canvas.drawRect(const ui.Rect.fromLTRB(-width5, -width5, -width10, width5), ui.Paint()..color = black); - canvas.drawRect(const ui.Rect.fromLTRB(-width5, -width5, width5, -width10), ui.Paint()..color = black); + canvas.drawRect(const ui.Rect.fromLTRB(-width3, -width3, width3, width3), + ui.Paint()..color = green); + canvas.drawRect( + const ui.Rect.fromLTRB(-width5, -width5, -width10, width5), + ui.Paint()..color = black); + canvas.drawRect( + const ui.Rect.fromLTRB(-width5, -width5, width5, -width10), + ui.Paint()..color = black); } final ui.Image incrementalMatrixImage = await toImage((ui.Canvas canvas) { @@ -692,7 +690,8 @@ void _matrix4x4CompositionTests() { }); }, width, height); - final bool areEqual = await fuzzyCompareImages(incrementalMatrixImage, combinedMatrixImage); + final bool areEqual = + await fuzzyCompareImages(incrementalMatrixImage, combinedMatrixImage); expect(areEqual, true); }); } @@ -940,7 +939,8 @@ void _pathTests() { // | | // 20 +-----------+ final SkPath segment = measure1.getSegment(5, 15, true); - expect(fromSkRect(segment.getBounds()), const ui.Rect.fromLTRB(15, 10, 20, 15)); + expect(fromSkRect(segment.getBounds()), + const ui.Rect.fromLTRB(15, 10, 20, 15)); final SkContourMeasure? measure2 = iter.next(); expect(measure2, isNull); @@ -985,8 +985,8 @@ void _canvasTests() { setUp(() { recorder = SkPictureRecorder(); - canvas = - recorder.beginRecording(toSkRect(const ui.Rect.fromLTRB(0, 0, 100, 100))); + canvas = recorder + .beginRecording(toSkRect(const ui.Rect.fromLTRB(0, 0, 100, 100))); }); tearDown(() {