Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Impeller] Drawing lines results in ugly, jagged and aliased lines with Impeller, compared to Skia. #138682

Open
2 tasks done
Sakari369 opened this issue Nov 19, 2023 · 26 comments
Labels
c: rendering UI glitches reported at the engine/skia or impeller rendering level e: impeller Impeller rendering backend issues and features requests engine flutter/engine repository. See also e: labels. found in release: 3.16 Found to occur in 3.16 found in release: 3.17 Found to occur in 3.17 has reproducible steps The issue has been confirmed reproducible and is ready to work on P2 Important issues not at the top of the work list team-engine Owned by Engine team triaged-engine Triaged by Engine team

Comments

@Sakari369
Copy link

Sakari369 commented Nov 19, 2023

Is there an existing issue for this?

Steps to reproduce

  1. Draw some vector shapes with canvas.drawPath, with line width thin enough / zoomed out enough
  2. Run with Impeller enabled on macOS or iOS
  3. Observe jagged and ugly lines, too opaque line drawing compared to Skia

Expected results

Would expect the vector path and line drawing to match that of Skia, at least close to the quality or producing beautiful results.

Actual results

The rendered lines are ugly, jagged, aliased and are too opaque and bright compared to Skia.

Code sample

Code sample

See repository with example generating the screenshots below: https://github.com/Sakari369/flutter_lines_bug

Screenshots or Video

Screenshots / Video demonstration

Line rendering with Skia:

Screenshot 2023-11-19 at 12 04 35

Line rendering with Impeller:

Screenshot 2023-11-19 at 12 03 57

Logs

Logs
If I paste the logs here, github wont let me make the issue

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.16.0, on macOS 14.1 23B74 darwin-arm64, locale en-FI)
    • Flutter version 3.16.0 on channel stable at /Users/sakari/dvl/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision db7ef5bf9f (4 days ago), 2023-11-15 11:25:44 -0800
    • Engine revision 74d16627b9
    • Dart version 3.2.0
    • DevTools version 2.28.2

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/sakari/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • ANDROID_HOME = /Users/sakari/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
    • 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.14.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (version unknown)
    • Android Studio at /Applications/Android Studio Preview.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
    ✗ Unable to determine Android Studio version.
    • Java version OpenJDK Runtime Environment (build 17.0.8+0-17.0.8b1000.22-10799086)

[✓] Android Studio (version 2023.1)
    • 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.7+0-17.0.7b1000.6-10550314)

[✓] VS Code (version 1.82.3)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension can be installed from:
      🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-arm64   • macOS 14.1 23B74 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 114.0.5735.90
    ! Error: Browsing on the local area network for Eero’s iPad. Ensure the device is unlocked and attached with a cable or associated with
      the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)
    ! Error: Browsing on the local area network for Sakari’s iPad. Ensure the device is unlocked and attached with a cable or associated
      with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)

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

! Doctor found issues in 1 category.

</details>
@Sakari369
Copy link
Author

Sakari369 commented Nov 19, 2023

Found this issue related, similar drawing bug: #121696
But not exactly the same, so made a new issue.

Hope that Impeller will at some point produce beautiful antialiased lines also, and at least if not exactly similar, then at least close to the results that Skia is achieving.

We can't use Impeller right now because of this issue, the vector shape drawing quality is a very important factor in the app we are currently developing. Good thing is it works very well with Skia already.

@danagbemava-nc danagbemava-nc added the in triage Presently being triaged by the triage team label Nov 20, 2023
@danagbemava-nc
Copy link
Member

Hi @Sakari369, can you check on the master channel to see if this issue reproduces for you? I can quite discern any different between SKIA (left) and Impeller(Right)

Screenshot 2023-11-20 at 10 17 23

@danagbemava-nc danagbemava-nc added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Nov 20, 2023
@Sakari369
Copy link
Author

Sakari369 commented Nov 20, 2023

Hey @danagbemava-nc, thanks for the fast reply.
Forgot to test on master channel of course :)

That's pretty interesting .. for me, the results are different still.
Updated to the master channel, flutter doctor says:

[✓] Flutter (Channel master, 3.17.0-10.0.pre.63, on macOS 14.1 23B74 darwin-arm64, locale en-FI)
    • Flutter version 3.17.0-10.0.pre.63 on channel master at /Users/sakari/dvl/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4cd32ffe78 (3 hours ago), 2023-11-20 06:38:17 -0500
    • Engine revision a93f20d892
    • Dart version 3.3.0 (build 3.3.0-149.0.dev)
    • DevTools version 2.30.0-dev.4

Wondering why this is working with you and not with me 🤔
Just to make sure, tested on iPad hardware also, and seeing the same results there.

Tried cleaning the project also before building, no change.
Tested with beta channel also, no change.

Saw some other comments in #121696 mentioning that similar issue would have been fixed already in master, and somebody saying it's still showing the erroneous drawing, maybe related ?

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Nov 20, 2023
@danagbemava-nc
Copy link
Member

danagbemava-nc commented Nov 21, 2023

I wonder if a difference is display resolution might be at play here. I tested on my iPad and I can see the difference clearly, on the latest master as well.

Labeling for further investigation.

code sample(for convenience)
import 'package:flutter/material.dart';
import 'dart:math';

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter lines antialiasing bug on Impeller',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: MyHomePage()
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class MyPainter extends CustomPainter {
  final double zoom;

  MyPainter({this.zoom = 0.3});

  @override
  void paint(Canvas canvas, Size size) {
    double strokeWidth = 2.0;

    Paint paintRed = Paint()
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke
      ..color = const Color(0xFFFF0000);

    Paint paintBlue = Paint()
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke
      ..color = const Color(0xFF0000FF);

    Paint paintGreen = Paint()
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke
      ..color = const Color(0xFF00FF00);

    double dist = 48;

    canvas.save();
    canvas.translate((size.width/2) - dist, size.height/2);
    canvas.scale(zoom, zoom);

    for (double radius=1100; radius>2; radius -= 64) {
      final path = Path();
      path.moveTo(radius * cos(0), radius * sin(0));
      for (int i = 0; i < 6; i++) {
        path.lineTo(
            radius * cos(pi * i / 3),
            radius * sin(pi * i / 3)
        );
      }
      path.close();
      canvas.drawPath(path, paintRed);
    }

    canvas.restore();

    canvas.save();
    canvas.translate((size.width/2), size.height/2);
    canvas.scale(zoom, zoom);

    for (double radius=1100; radius>2; radius -= 64) {
      final path = Path();
      path.moveTo(radius * cos(0), radius * sin(0));
      for (int i = 0; i < 6; i++) {
        path.lineTo(
            radius * cos(pi * i / 3),
            radius * sin(pi * i / 3)
        );
      }
      path.close();
      canvas.drawPath(path, paintBlue);
    }

    canvas.restore();

    canvas.save();
    canvas.translate((size.width/2) + dist, size.height/2);
    canvas.scale(zoom, zoom);

    for (double radius=1100; radius>2; radius -= 64) {
      final path = Path();
      path.moveTo(radius * cos(0), radius * sin(0));
      for (int i = 0; i < 6; i++) {
        path.lineTo(
            radius * cos(pi * i / 3),
            radius * sin(pi * i / 3)
        );
      }
      path.close();
      canvas.drawPath(path, paintGreen);
    }

    canvas.restore();

  }

  @override bool shouldRepaint(CustomPainter oldDelegate) => true;
}

class _MyHomePageState extends State<MyHomePage>
  with SingleTickerProviderStateMixin {

  late AnimationController _controller;
  late Animation<double> _zoomAnimation;

  @override
  void initState() {
    super.initState();

    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 15),
    );

    _zoomAnimation = Tween<double>(begin: 0.10, end: 0.20)
        .animate(_controller)
      ..addListener(() {
        setState(() {});
      });

    _controller.forward();
  }

  @override void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF000000),
      body: Center(
        child: CustomPaint(
          size: const Size(1280, 1280), // size of canvas
          painter: MyPainter(zoom: _zoomAnimation.value),
        ),
      )
    );
  }
}
screenshots

SKIA

IMPELLER

flutter doctor -v
[!] Flutter (Channel stable, 3.16.0, on macOS 14.1.1 23B81 darwin-arm64, locale en-GB)
    • Flutter version 3.16.0 on channel stable at /Users/nexus/dev/sdks/flutter
    ! Warning: `flutter` on your path resolves to /Users/nexus/dev/sdks/flutters/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutter. Consider adding /Users/nexus/dev/sdks/flutter/bin to the front of your path.
    ! Warning: `dart` on your path resolves to /Users/nexus/dev/sdks/flutters/bin/dart, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutter. Consider adding /Users/nexus/dev/sdks/flutter/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision db7ef5bf9f (6 days ago), 2023-11-15 11:25:44 -0800
    • Engine revision 74d16627b9
    • Dart version 3.2.0
    • DevTools version 2.28.2
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.

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

[✓] Xcode - develop for iOS and macOS (Xcode 15.0)
    • Xcode at /Applications/Xcode-15.0.0-Release.Candidate.app/Contents/Developer
    • Build 15A240d
    • CocoaPods version 1.13.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.3)
    • Android Studio at /Users/nexus/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.6b829.9-10027231)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.2.5)
    • IntelliJ at /Users/nexus/Applications/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 76.3.4
    • Dart plugin version 232.10072.19

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

[✓] Connected device (4 available)
    • Nexus (mobile)       • 00008020-001875E83A38002E • ios            • iOS 17.1.1 21B91
    • Dean’s iPad (mobile) • 00008103-000825C811E3401E • ios            • iOS 17.1 21B74
    • macOS (desktop)      • macos                     • darwin-arm64   • macOS 14.1.1 23B81 darwin-arm64
    • Chrome (web)         • chrome                    • web-javascript • Google Chrome 119.0.6045.159

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

! Doctor found issues in 1 category.
[✓] Flutter (Channel master, 3.17.0-12.0.pre.39, on macOS 14.1.1 23B81 darwin-arm64, locale en-GB)
    • Flutter version 3.17.0-12.0.pre.39 on channel master at /Users/nexus/dev/sdks/flutters
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision b6ef78e955 (3 hours ago), 2023-11-20 23:37:25 -0500
    • Engine revision 70b1c73412
    • Dart version 3.3.0 (build 3.3.0-152.0.dev)
    • DevTools version 2.30.0-dev.4

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

[✓] Xcode - develop for iOS and macOS (Xcode 15.0)
    • Xcode at /Applications/Xcode-15.0.0-Release.Candidate.app/Contents/Developer
    • Build 15A240d
    • CocoaPods version 1.13.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.3)
    • Android Studio at /Users/nexus/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.6b829.9-10027231)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.2.5)
    • IntelliJ at /Users/nexus/Applications/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 76.3.4
    • Dart plugin version 232.10072.19

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

[✓] Connected device (4 available)
    • Nexus (mobile)       • 00008020-001875E83A38002E • ios            • iOS 17.1.1 21B91
    • Dean’s iPad (mobile) • 00008103-000825C811E3401E • ios            • iOS 17.1 21B74
    • macOS (desktop)      • macos                     • darwin-arm64   • macOS 14.1.1 23B81 darwin-arm64
    • Chrome (web)         • chrome                    • web-javascript • Google Chrome 119.0.6045.159

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

• No issues found!

@danagbemava-nc danagbemava-nc added engine flutter/engine repository. See also e: labels. c: rendering UI glitches reported at the engine/skia or impeller rendering level has reproducible steps The issue has been confirmed reproducible and is ready to work on e: impeller Impeller rendering backend issues and features requests team-engine Owned by Engine team found in release: 3.16 Found to occur in 3.16 found in release: 3.17 Found to occur in 3.17 and removed in triage Presently being triaged by the triage team labels Nov 21, 2023
@github-project-automation github-project-automation bot moved this to 🤔 Needs Triage in Impeller Nov 21, 2023
@Sakari369
Copy link
Author

Sakari369 commented Nov 22, 2023

I wonder if a difference is display resolution might be at play here. I tested on my iPad and I can see the difference clearly, on the latest master as well.

I tested on my 2560x1440 resolution external display, and also on my MacBook Pro retina display, and on two different iPads, all show the buggy behaviour with Impeller.

Thank you for taking this forwards!

@jonahwilliams jonahwilliams added P2 Important issues not at the top of the work list triaged-engine Triaged by Engine team labels Nov 27, 2023
@chinmaygarde chinmaygarde moved this from 🤔 Needs Triage to 🐞 Bugs in Impeller Nov 30, 2023
@chinmaygarde chinmaygarde changed the title Drawing lines results in ugly, jagged and aliased lines with Impeller, compared to Skia [Impeller] Drawing lines results in ugly, jagged and aliased lines with Impeller, compared to Skia. Dec 2, 2023
@chinmaygarde chinmaygarde added the slimpeller Engine binary size reduction. go/slimpeller label May 15, 2024
@github-project-automation github-project-automation bot moved this to Needs Triage in Slimpeller May 15, 2024
@chinmaygarde chinmaygarde moved this from Needs Triage to Blockers in Slimpeller May 15, 2024
@Sakari369
Copy link
Author

Just to clarify, this same behaviour can be seen on iOS and Android.
Was discussing this briefly with @jonahwilliams on Twitter, he said that macOS Impeller wont ship this year, but wanted to clarify that the same behaviour is seen on iOS and Android builds with Impeller.

@jonahwilliams
Copy link
Member

I investigated this a bit and found that we're not hitting the minimum stroke width, therefore the problem is primarily driven by anti-aliasing differences between Impeller and Skia.

@Sakari369
Copy link
Author

I investigated this a bit and found that we're not hitting the minimum stroke width, therefore the problem is primarily driven by anti-aliasing differences between Impeller and Skia.

Thanks for the update, yeah that's what I thought by looking at the line drawing differences.
Hopefully you can reach the same quality of antialiasing as Skia, I did look into a bit and seems Skia is using a very high quality antialiasing method, as discussed in this ticket #121696

@jonahwilliams
Copy link
Member

@chinmaygarde had the suggestion that we could adjust the sizes of the lines + the apparent opacity to easily give them a better appearance. Waiting for more details on that.

@jonahwilliams
Copy link
Member

The more I look at this the less I can tell a difference between Skia and Impeller. Two questions Sakari369 , does this repro for you at ToT and what particular iPad models does it repro on otherwise?

Its possible the iPhone I'm using is high enough resolution that it doesn't matter.

@Sakari369
Copy link
Author

Sakari369 commented Jun 10, 2024

The more I look at this the less I can tell a difference between Skia and Impeller. Two questions Sakari369 , does this repro for you at ToT and what particular iPad models does it repro on otherwise?

Its possible the iPhone I'm using is high enough resolution that it doesn't matter.

The difference is definitely there.
Can you check on the iOS emulator ? On a non retina screen should be easy to spot.
Maybe on an iPhone small screen it's not so visible.

But at least the line widths below 1.0 (?) don't even matter with Impeller right now, and especially the interference patterns created by small lines, there you can see it clearly.

Can you see the difference here?
https://youtu.be/_7iZMPaqC20?si=fW5dYrHpihrnHMuK&t=1417

I tried to showcase it here on one of the progress videos of our app.

What is ToT ?

@jonahwilliams
Copy link
Member

ToT is tip of tree aka latest master channel.

@Sakari369
Copy link
Author

ToT is tip of tree aka latest master channel.

Ah okay, I have not tested on that. Tested on 3.22, I can try master branch soon and report back 👍

@chinmaygarde
Copy link
Member

We've been discussing various ways of addressing such differences within the bounds of the techniques currently used and I think we have a few leads. As I understand, this difference occurs when the stroke width is not quite a hairline but also not too wide. For both hairlines and wide stroke sizes, results are acceptable. The observation being that thin lines in a narrow stroke width range are "too opaque".

The current thinking is that we can make the falloff more prominent by adjusting the sample contributions and also perhaps by adjusting the opacity within this narrow range of stroke widths (though Jonah mentions he didn't get good results using just this tweak). I prototyped a few techniques that showed some promise by allowing us to tinker on these parameters.

Image

Where I am stuck at the moment is figuring out a device on which this happens reliably to ensure we just don't make things worse. My observations on all devices I have are similar to the earlier comment. For this reason, I am removing this issue from the slimpeller blockers as those track on-device blockers. It may also be a good idea to port the the original posters code to a playground so we can tinker more easily as I found going through the framework to the adjust sizes and such to be a bit of a pain.

More to come.

@chinmaygarde chinmaygarde removed the slimpeller Engine binary size reduction. go/slimpeller label Jun 18, 2024
@Sakari369
Copy link
Author

Sakari369 commented Jun 20, 2024

Hey, thanks for looking at this.

Easy way to see difference, is to run the provided example inside iOS Simulator, I did so using the 10.9 inch iPad device.
Upgraded to current Flutter master channel:

Flutter 3.23.0-13.0.pre.281 • channel master • https://github.com/flutter/flutter.git
Framework • revision 0674f46e9f (19 minutes ago) • 2024-06-20 18:02:07 +0200
Engine • revision dd37cefd4a
Tools • Dart 3.5.0 (build 3.5.0-281.0.dev) • DevTools 2.36.0

I ran the provided example project, both with '--no-enable-impeller' and without adding that flag using the Impeller engine.
I took screenshots once the animation had executed.

Here are the shots, magnified 300% to see more clearly:

First, Skia version:

Screenshot 2024-06-20 at 19 31 04

Then the Impeller version:

Screenshot 2024-06-20 at 19 29 44

Here are versions with exposure increased in Affinity Photo, to see the difference more clearly:

First Skia, looking good:

Screenshot 2024-06-20 at 19 38 08

Then Impeller, blocking us from using this:

Screenshot 2024-06-20 at 19 37 49

We are developing an application that draws a lot of thing vector lines, and the quality difference is very noticeable.

I can maybe turn the project into a playground, but it is very easy to already run through the example project, no ?

Anyway. maybe it is not so easy to see on a high DPI display, so I recommend running this on a normal DPI monitor inside the Simulator, you should see the difference clearly. And if it happens in the simulator, it is happening on the device also.

@jonahwilliams
Copy link
Member

And if it happens in the simulator, it is happening on the device also.

If all the devices we support have retina-ish I'm not sure that is necessarily the case? We certainly don't want things to look bad on the simulator at any rate, but this may be sim specific for your example.

@Sakari369
Copy link
Author

Sakari369 commented Jun 20, 2024

And if it happens in the simulator, it is happening on the device also.

If all the devices we support have retina-ish I'm not sure that is necessarily the case? We certainly don't want things to look bad on the simulator at any rate, but this may be sim specific for your example.

Well I've observed the line rendering both on the device and simulator, and it is quite the same.
It is just harder to see on the device, due to higher DPI.

Unfortunately I dont have my developer license right now up to date, waiting to get that re-newed, should be able to test next week on a device and try to showcase it from there.

But according to my experience the simulator and device render the same contents, after all, what would be the point if that would differ ?

Anyway the quality difference is more pronounced when you have a lot of lines going on and interfering, here are a couple of shots from our in development app:

(expand images to see the difference better)

With Skia:

Screenshot 2024-06-20 at 20 00 42

With Impeller:

Screenshot 2024-06-20 at 20 03 03

Trust me, I have looked at how to render beautiful lines for a long time, implemented many different methods myself also just to test out what works, I've written my own shaders for rendering lines, and I've observed and tested many different methods for rendering beautiful lines, it's not definitely an easy problem to solve with high quality results.

Skia has nailed down that rendering to a point, so not wondering that Impeller has trouble matching that quality. We can always hopefully continue using Skia backend, so in that matter, it's not a total killer for us, and I know that our usecase is out of the ordinary, but we are trying to create a truly beautiful application here, and this kind of small details matter.

@Sakari369
Copy link
Author

Sakari369 commented Jun 20, 2024

I can make a playground demo that demonstrates the quality issues better and easier, but can't get to it right now as have other deadline on my back, but maybe that can help you see this quality difference ?

@jonahwilliams
Copy link
Member

No need to make a playground or anything like that. I want to make a distinction here, its not that we're looking for proof that there is pixelation on a desktop device, its that we're uncertain that there is pixelation on a physical iOS device. The artifacts are a result of the DPI of the screen. On mobile devices (and iOS devices in particular), the DPI is much higher than desktop monitors, which is why we don't think this is necessarily a problem for real devices.

Unfortunately the simulators can only simulate so much. They can't effectively emulate the hardware features of iOS devices (which is why they're unusable for performance metrics) and they can't simulate the higher DPI either.

Skia has very nice analytical approaches for AA. But we don't think we need these approaches for mobile screens;not using them lets Impeller be faster + smaller, while also fixing well known rendering artifacts caused by the analytical AA like #14288 .

Now if this is a problem on physical devices, we can always use the technique that @chinmaygarde outlined to pump the fidelity a bit.

@Sakari369
Copy link
Author

Sakari369 commented Jun 20, 2024

No need to make a playground or anything like that. I want to make a distinction here, its not that we're looking for proof that there is pixelation on a desktop device, its that we're uncertain that there is pixelation on a physical iOS device. The artifacts are a result of the DPI of the screen. On mobile devices (and iOS devices in particular), the DPI is much higher than desktop monitors, which is why we don't think this is necessarily a problem for real devices.

Unfortunately the simulators can only simulate so much. They can't effectively emulate the hardware features of iOS devices (which is why they're unusable for performance metrics) and they can't simulate the higher DPI either.

Skia has very nice analytical approaches for AA. But we don't think we need these approaches for mobile screens;not using them lets Impeller be faster + smaller, while also fixing well known rendering artifacts caused by the analytical AA like #14288 .

Now if this is a problem on physical devices, we can always use the technique that @chinmaygarde outlined to pump the fidelity a bit.

Okay, making me jump through some hoops here :) but it seems I can run it on my device without having a valid ADC license these days, so I ran it on my 10.2" 9th gen iPad (using current master), here are the screenshots from the actual device:

Skia:

IMG_0459

Impeller:

IMG_0458

I don't know maybe you just didn't see the difference when testing, but I guess it's pretty obvious ? Expand again and compare the full resolution screenshots.

Hoping of course that quality would be up to par with Skia, as Skia line rendering is very essential to our app.
Anyway thanks again for looking at this, hoping that in the future both are up to par.

@jonahwilliams
Copy link
Member

Thanks, we'll look at getting a similar device so we can eyeball it in person.

@Sakari369
Copy link
Author

Sakari369 commented Jun 21, 2024

Skia has very nice analytical approaches for AA. But we don't think we need these approaches for mobile screens;not using them lets Impeller be faster + smaller, while also fixing well known rendering artifacts caused by the analytical AA like #14288 .

Now if this is a problem on physical devices, we can always use the technique that @chinmaygarde outlined to pump the fidelity a bit.

A suggestion here, how about having quality option for the line and vector rendering ?
For example node-canvas has multiple options for determining the rendering quality: https://github.com/Automattic/node-canvas?tab=readme-ov-file#canvasrenderingcontext2dquality

I would see it useful for applications that need to draw high quality vector graphics, to have analytical AA, with the best possible quality.

For drawing the UI you would not probably need such high quality rendering.
This would enable Impeller to support drawing applications that many people are for sure going to make.

Personally, I love what Skia has done with the vector and line rendering quality. Would be a shame if you could not do that with Impeller at all.

Of course platform views might be an option to do that, just have a single texture view that is rendered on the platform side with Skia linked to the application, if it's not possible with Impeller in the future. Or do you know if there are any plans to support like having Skia render only like contents of a CustomPainter for example ?

Just thinking out loud here.

@ZahraVe

This comment was marked as off-topic.

@jonahwilliams
Copy link
Member

@ZahraVe please file a new bug.

@jonahwilliams
Copy link
Member

We have a prototype of anti aliased lines we're currentlly investigating how much work it is to add to Impeller

@Sakari369
Copy link
Author

Sakari369 commented Mar 5, 2025

We have a prototype of anti aliased lines we're currentlly investigating how much work it is to add to Impeller

Thanks for the update! Was wondering if any update on this, as 3.29 removing opting out of Skia on iOS is gonna prevent us from updating from 3.27.

Let me know if you need any help in testing !

github-merge-queue bot pushed a commit that referenced this issue Mar 24, 2025
issue: #138682
design doc:
https://docs.google.com/document/d/19I6ToHCMlSgSava-niFWzMLGJEAd-rYiBQEGOMu8IJg/edit?tab=t.0

This puts an experimental line drawing approach behind the following
flags:
  - iOS: `FLTAntialiasLines` boolean, default NO
- Android: `io.flutter.embedding.android.ImpellerAntialiasLines`
boolean, default false

Right now they just support DrawLines and don't support line caps.

A test was added that works as a playground for vulkan, opengles and
metal. Only the Metal version was turned into a golden test though here.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: rendering UI glitches reported at the engine/skia or impeller rendering level e: impeller Impeller rendering backend issues and features requests engine flutter/engine repository. See also e: labels. found in release: 3.16 Found to occur in 3.16 found in release: 3.17 Found to occur in 3.17 has reproducible steps The issue has been confirmed reproducible and is ready to work on P2 Important issues not at the top of the work list team-engine Owned by Engine team triaged-engine Triaged by Engine team
Projects
No open projects
Status: 🐞 Bugs
Development

No branches or pull requests

5 participants