Skip to content

[Impeller] Impeller RRect blur is slower than Skia's cached blur shadows. #148496

@voxelbee

Description

@voxelbee

Steps to reproduce

  1. Create a new project use the code sample bellow and make sure you are running using impeller backend.
  2. Scroll in the list and there will be a large amount of jank during scrolling.
  3. Make sure to use a custom painter with a shader and layers as show in the example code. This makes the jank much more visible.

Code sample

Code sample
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ListView.builder(
        itemCount: 100,
        itemBuilder: (context, index) {
          return ListItemWidget(
            key: ValueKey<int>(index),
            index: index,
          );
        },
      ),
    );
  }
}

class ListItemWidget extends StatelessWidget {
  const ListItemWidget({required this.index, super.key});

  final int index;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8),
      child: Painter(
        child: Card(
          child: ListTile(
            title: Text('Item $index'),
          ),
        ),
      ),
    );
  }
}

class Painter extends StatelessWidget {
  const Painter({required this.child, super.key});

  final Widget child;

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: _CustomPainter(),
      child: child,
    );
  }
}

class _CustomPainter extends CustomPainter {
  _CustomPainter();

  static const List<Offset> bubbles = [
    Offset(0.2, 0.2),
    Offset(0.8, 0.8),
    Offset(0.5, 0.5),
  ];

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..style = PaintingStyle.fill
      ..filterQuality = FilterQuality.low
      ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 35);

    final rect = (Offset.zero & size).inflate(40);

    canvas.saveLayer(rect, Paint());
    for (final bubble in bubbles) {
      final position = Offset(
        size.width * (1 - (bubble.dx * 0.4)),
        size.height * bubble.dy,
      );

      canvas.drawCircle(
        position,
        50,
        paint..color = Colors.red,
      );
    }

    canvas
      ..drawRect(
        rect,
        Paint()
          ..shader = const LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            colors: [
              Colors.transparent,
              Colors.white,
              Colors.white,
              Colors.transparent,
            ],
            stops: [0.2, 0.3, 0.7, 0.8],
          ).createShader(rect)
          ..blendMode = BlendMode.dstIn,
      )
      ..drawRect(
        rect,
        Paint()
          ..shader = const LinearGradient(
            colors: [
              Colors.transparent,
              Colors.white,
              Colors.white,
              Colors.transparent,
            ],
            stops: [0.06, 0.1, 0.85, 0.94],
          ).createShader(rect)
          ..blendMode = BlendMode.dstIn,
      )
      ..restore();
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

Performance profiling on master channel

  • The issue still persists on the master channel

Timeline Traces

Timeline Traces JSON

dart_devtools_2024-05-16_17 42 26.249.json.zip

Screenshot 2024-05-16 at 4 46 42 PM

Video demonstration

Video demonstration

[Upload media here]

What target platforms are you seeing this bug on?

iOS

OS/Browser name and version | Device information

iOS 17.4.1
IPhone 13 Pro Max

Does the problem occur on emulator/simulator as well as on physical devices?

Unknown

Is the problem only reproducible with Impeller?

Yes

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[✓] Flutter (Channel master, 3.22.0-35.0.pre.35, on macOS 14.0 23A344 darwin-arm64, locale en-US)
    • Flutter version 3.22.0-35.0.pre.35 on channel master at /opt/homebrew/Caskroom/flutter/3.19.2/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision c719f03ded (18 minutes ago), 2024-05-16 18:12:33 +0200
    • Engine revision 460df6caef
    • Dart version 3.5.0 (build 3.5.0-160.0.dev)
    • DevTools version 2.36.0-dev.10

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
    • Android SDK at /Users/peytonhammersley/Library/Android/sdk
    • Platform android-34, build-tools 33.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15A507
    • CocoaPods version 1.15.2

[✓] Android Studio (version 2022.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

[✓] VS Code (version 1.87.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.86.0

[✓] VS Code (version 1.90.0-insider)
    • VS Code at /Applications/Visual Studio Code - Insiders.app/Contents
    • Flutter extension version 3.88.0

[✓] Connected device (2 available)
    • Peyton’s iPhone (mobile)        • 00008110-000A1C2811A3801E • ios    • iOS 17.4.1 21E236
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad     • darwin • macOS 14.0 23A344 darwin-arm64

[✓] Network resources
    • All expected network resources are available.

• No issues found!

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work liste: impellerImpeller rendering backend issues and features requestsfrom: performance templateIssues created via a performance issue templateteam-engineOwned by Engine teamtriaged-engineTriaged by Engine team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions