diff --git a/lib/web_ui/lib/src/engine/canvas_pool.dart b/lib/web_ui/lib/src/engine/canvas_pool.dart index 2fb4ad478b16c..4fbc1eecf21f5 100644 --- a/lib/web_ui/lib/src/engine/canvas_pool.dart +++ b/lib/web_ui/lib/src/engine/canvas_pool.dart @@ -934,6 +934,7 @@ class ContextStateHandle { } ui.MaskFilter? _currentFilter; + String? _currentFilterCss; SurfacePaintData? _lastUsedPaint; /// Currently active shader bounds. @@ -1003,19 +1004,20 @@ class ContextStateHandle { } final ui.MaskFilter? maskFilter = paint.maskFilter; - if (!_renderMaskFilterForWebkit) { - if (_currentFilter != maskFilter) { - _currentFilter = maskFilter; - context.filter = maskFilterToCanvasFilter(maskFilter); - } - } else { - // WebKit does not support the `filter` property. Instead we apply a - // shadow to the shape of the same color as the paint and the same blur - // as the mask filter. - // - // Note that on WebKit the cached value of _currentFilter is not useful. - // Instead we destructure it into the shadow properties and cache those. - if (maskFilter != null) { + if (maskFilter != null) { + if (!_renderMaskFilterForWebkit) { + if (_currentFilter != maskFilter) { + _currentFilter = maskFilter; + _currentFilterCss = maskFilterToCanvasFilter(maskFilter); + } + context.filter = _currentFilterCss; + } else { + // WebKit does not support the `filter` property. Instead we apply a + // shadow to the shape of the same color as the paint and the same blur + // as the mask filter. + // + // Note that on WebKit the cached value of _currentFilter is not useful. + // Instead we destructure it into the shadow properties and cache those. context.save(); context.shadowBlur = convertSigmaToRadius(maskFilter.webOnlySigma); // Shadow color must be fully opaque. diff --git a/lib/web_ui/test/html/compositing/canvas_mask_filter_golden_test.dart b/lib/web_ui/test/html/compositing/canvas_mask_filter_golden_test.dart index 840bb0c23332d..e38aa59726892 100644 --- a/lib/web_ui/test/html/compositing/canvas_mask_filter_golden_test.dart +++ b/lib/web_ui/test/html/compositing/canvas_mask_filter_golden_test.dart @@ -150,6 +150,38 @@ Future testMain() async { await canvasScreenshot(rc, 'mask_filter_transformed_$browser', region: screenRect); }); + + test('multiple MaskFilter.blur in $browser', () async { + const double screenWidth = 300.0; + const double screenHeight = 300.0; + const ui.Rect screenRect = + ui.Rect.fromLTWH(0, 0, screenWidth, screenHeight); + + ContextStateHandle.debugEmulateWebKitMaskFilter = isWebkit; + final RecordingCanvas rc = RecordingCanvas(screenRect); + + final SurfacePaint paint = SurfacePaint() + ..maskFilter = const ui.MaskFilter.blur(ui.BlurStyle.normal, 5); + rc.save(); + rc.drawCircle(const ui.Offset(150, 150), 100, + paint..color = const ui.Color(0xFFC8C800)); + rc.restore(); + rc.save(); + rc.drawCircle(const ui.Offset(150, 150), 50, + paint..color = const ui.Color(0xFFC800C8)); + rc.restore(); + rc.save(); + rc.drawCircle( + const ui.Offset(150, 150), + 20, + paint + ..color = const ui.Color(0xFF00C8C8) + ..maskFilter = const ui.MaskFilter.blur(ui.BlurStyle.normal, 10)); + rc.restore(); + + await canvasScreenshot(rc, 'multiple_mask_filter_$browser', + region: screenRect); + }); } testMaskFilterBlur();