Skip to content

[Impeller][Windows][OpenGLESSDF] Animated rounded BoxDecoration renders jagged and briefly develops square corners during animation #189827

Closed

Description

@Razorex001

Steps to reproduce

Use the provided Code Sample to reproduce the issue.

  1. Run the provided code sample on Windows with Impeller enabled:
    flutter run -d windows --debug
  2. Confirm that the console reports:
    Using the Impeller rendering backend (OpenGLESSDF).
  3. Observe the curved cyan border around the selected indicator.
  4. Click Library and Catalog repeatedly and observe the indicator during its animation.
  5. Run the same sample with Skia for comparison:
    flutter run -d windows --debug --no-enable-impeller

Also, see the provided screenshots with impeller and with skia

With Impeller enabled on Windows using OpenGLESSDF backend, in all my app curved borders and lines appear significantly more jagged than with Skia. The attached minimal reproduction demonstrates this with an animated rounded BoxDecoration.
A second issue occurs during the animation: the cyan indicator briefly loses its rounded appearance and displays square corners at intermediate positions, which doesn't happen with Skia.

Not sure if it's relevant, but here's also some info about my pc:
GPU: AMD Radeon RX 580 Series 4GB
Display driver: 31.0.21923.11000
Driver date: July 1, 2025
AMD Software: Adrenalin Edition 25.8.1

Expected results

The rounded indicator should render with smooth, consistently anti-aliased curved edges, matching the visual quality produced by Skia. Its 22px corner radius should remain intact throughout the entire alignment animation.

Actual results

With Impeller using the Windows OpenGLESSDF backend, the indicator’s curved border appears visibly jagged/stair-stepped compared with Skia. During the animation, the cyan indicator also briefly develops square corners at intermediate positions. Neither artifact occurs when running the same code with Skia.

Code sample

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

void main() {
  runApp(const MaterialApp(home: SliderReproduction()));
}

class SliderReproduction extends StatefulWidget {
  const SliderReproduction({super.key});

  @override
  State<SliderReproduction> createState() => _SliderReproductionState();
}

class _SliderReproductionState extends State<SliderReproduction> {
  static const Color neonColor = Color(0xFF00FFFF);

  bool _isCatalog = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF101010),
      body: Center(
        child: SizedBox(
          width: 220,
          child: Container(
            height: 44,
            decoration: BoxDecoration(
              color: Colors.black.withValues(alpha: 0.4),
              borderRadius: BorderRadius.circular(22),
              border: Border.all(color: Colors.white.withValues(alpha: 0.05)),
            ),
            child: Stack(
              children: [
                AnimatedAlign(
                  alignment: _isCatalog
                      ? Alignment.centerRight
                      : Alignment.centerLeft,
                  duration: const Duration(milliseconds: 300),
                  curve: Curves.easeOutCubic,
                  child: FractionallySizedBox(
                    widthFactor: 0.5,
                    heightFactor: 1,
                    child: Container(
                      decoration: BoxDecoration(
                        color: neonColor.withValues(alpha: 0.15),
                        borderRadius: BorderRadius.circular(22),
                        border: Border.all(
                          color: neonColor.withValues(alpha: 0.6),
                          width: 1.5,
                        ),
                        boxShadow: [
                          BoxShadow(
                            color: neonColor.withValues(alpha: 0.2),
                            blurRadius: 8,
                            spreadRadius: 0,
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
                Row(
                  children: [
                    Expanded(
                      child: GestureDetector(
                        behavior: HitTestBehavior.opaque,
                        onTap: () {
                          setState(() {
                            _isCatalog = false;
                          });
                        },
                        child: const Center(
                          child: Text(
                            'Screen 1',
                            style: TextStyle(color: Colors.white),
                          ),
                        ),
                      ),
                    ),
                    Expanded(
                      child: GestureDetector(
                        behavior: HitTestBehavior.opaque,
                        onTap: () {
                          setState(() {
                            _isCatalog = true;
                          });
                        },
                        child: const Center(
                          child: Text(
                            'Screen 2',
                            style: TextStyle(color: Colors.white),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration

1st one is Impeller, 2nd one is Skia.
[

Image Image

]

Logs

Logs
[IMPORTANT:flutter/shell/platform/embedder/embedder_surface_gl_impeller.cc(126)] Using the Impeller rendering backend (OpenGLESSDF).

Flutter Doctor output

Doctor output
PS C:\Users\moret> flutter doctor -v
[√] Flutter (Channel master, 3.47.0-1.0.pre-165, on Microsoft Windows [Version 10.0.19045.7548], locale it-IT) [2,6s]
    • Flutter version 3.47.0-1.0.pre-165 on channel master at C:\src\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 3f02ab8a54 (4 hours ago), 2026-07-22 00:23:08 +0000
    • Engine revision c0c75a5bc6
    • Dart version 3.14.0 (build 3.14.0-46.0.dev)
    • DevTools version 2.60.0
    • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android,
      enable-ios, cli-animations, enable-native-assets, enable-record-use, enable-swift-package-manager,
      omit-legacy-version-file, enable-windowing, enable-lldb-debugging, enable-uiscene-migration, enable-riscv64

[√] Windows Version (10 Pro 64-bit, 22H2, 2009) [2,9s]

[√] Android toolchain - develop for Android devices (Android SDK version 36.1.0) [2,7s]
    • Android SDK at C:\Users\moret\AppData\Local\Android\sdk
    • Emulator version 36.6.11.0 (build_id 15507667) (CL:N/A)
    • Platform android-36.1, build-tools 36.1.0
    • Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 21.0.10+-14961533-b1163.108)
    • All Android licenses accepted.

[√] Chrome - develop for the web [117ms]
    • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.14.36) [116ms]
    • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
    • Visual Studio Community 2022 version 17.14.37502.11
    • Windows 10 SDK version 10.0.26100.0

[√] Connected device (3 available) [564ms]
    • Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.19045.7548]
    • Chrome (web)      • chrome  • web-javascript • Google Chrome 150.0.7871.129
    • Edge (web)        • edge    • web-javascript • Microsoft Edge 150.0.4078.83

[√] Network resources [573ms]
    • All expected network resources are available.

• No issues found!

Activity

  1. suryaKommana2662 commented on Jul 22, 2026

    @suryaKommana2662

    @Razorex001 Thanks for the report. I was able to reproduce the reported rendering issue on Windows. When running the provided reproduction with flutter run -d windows --debug I can observe the jagged edges on the rounded indicator, consistent with the behavior described in this issue. However, when running the same reproduction with flutter run -d windows --debug --no-enable-impeller the jagged edges are no longer present, and the rounded edges render as expected.

    This confirms that the issue is reproducible with the Impeller rendering backend and does not occur when using Skia. I have attached a screenshot showing the jagged edges observed with Impeller.

    Image

    Flutter Doctor Output:

    [√] Flutter (Channel master, 3.47.0-1.0.pre-169, on Microsoft Windows [Version 10.0.26200.8875], locale en-IN) [3.3s]
        • Flutter version 3.47.0-1.0.pre-169 on channel master at C:\flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 468c2c9d78 (2 hours ago), 2026-07-22 07:51:27 +0000
        • Engine revision 468c2c9d78
        • Dart version 3.14.0 (build 3.14.0-46.0.dev)
        • DevTools version 2.60.0
        • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios,
          cli-animations, enable-native-assets, enable-record-use, enable-swift-package-manager, omit-legacy-version-file, enable-windowing,
          enable-lldb-debugging, enable-uiscene-migration, enable-riscv64
    
    [√] Windows Version (Windows 11 or higher, 25H2, 2009) [1,414ms]
    
    [√] Android toolchain - develop for Android devices (Android SDK version 36.1.0) [4.1s]
        • Android SDK at C:\Android\Sdk
        • Emulator version 36.5.11.0 (build_id 15261927) (CL:N/A)
        • Platform android-36.1, build-tools 36.1.0
        • Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java
          This is the JDK bundled with the latest Android Studio installation on this machine.
          To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
        • Java version OpenJDK Runtime Environment (build 21.0.10+-14961533-b1163.108)
        • All Android licenses accepted.
    
    [√] Chrome - develop for the web [151ms]
        • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe
    
    [√] Visual Studio - develop Windows apps (Visual Studio Community 2026 18.6.1) [149ms]
        • Visual Studio at C:\Program Files\Microsoft Visual Studio\18\Community
        • Visual Studio Community 2026 version 18.6.11819.183
        • Windows 10 SDK version 10.0.26100.0
    
    [√] Connected device (3 available) [375ms]
        • Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.26200.8875]
        • Chrome (web)      • chrome  • web-javascript • Google Chrome 150.0.7871.129
        • Edge (web)        • edge    • web-javascript • Microsoft Edge 150.0.4078.83
    
    [√] Network resources [770ms]
        • All expected network resources are available.
    
    • No issues found!
  2. added
    platform-windowsBuilding on or for Windows specifically
    c: renderingUI glitches reported at the engine/skia or impeller rendering level
    e: impellerImpeller rendering backend issues and features requests
    and removed
    in triagePresently being triaged by the triage team
    on Jul 22, 2026
  3. Razorex001 commented on Jul 22, 2026

    @Razorex001
    Author

    @suryaKommana2662 Were you able to reproduce also the sqared corners during the animation? It happens for a very brief moment but it's definitely there. A bit hard to take a screenshot of it though.

    Edit: The briefly square corners during the toggle animation may be related to #189807, because the animated rounded rectangle passes through fractional dimensions. However, the jagged/aliased rounded outline seems to be a different issue.

  4. KuiperBelt-LAW commented on Jul 23, 2026

    @KuiperBelt-LAW

    I got same problem even in static page.
    GPU: NVIDIA T600 Laptop GPU
    with beta sdk >= 3.46
    Image

  5. KuiperBelt-LAW commented on Jul 23, 2026

    @KuiperBelt-LAW

    PowerShell 7.6.3
    PS C:\Users\LGC> flutter doctor -v
    Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source!
    [√] Flutter (Channel beta, 3.47.0-0.1.pre, on Microsoft Windows [版本 10.0.19044.7548], locale zh-CN) [364ms]
    • Flutter version 3.47.0-0.1.pre on channel beta at C:\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision bd1e75d (13 days ago), 2026-07-09 13:32:07 -0700
    • Engine revision bbd1586
    • Dart version 3.13.0 (build 3.13.0-282.1.beta)
    • DevTools version 2.59.0
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn
    • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android,
    enable-ios, cli-animations, enable-native-assets, enable-record-use, enable-swift-package-manager,
    omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration

    [√] Windows Version (10 IoT 企业版 LTSC 64-bit, 21H2, 2009) [1,931ms]

    [√] Android toolchain - develop for Android devices (Android SDK version 37.0.0) [13.6s]
    • Android SDK at C:\Users\LGC\AppData\Local\Android\sdk
    • Emulator version 36.4.9.0 (build_id 14788078) (CL:N/A)
    • Platform android-36.1, build-tools 37.0.0
    • Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java
    This is the JDK bundled with the latest Android Studio installation on this machine.
    To manually set the JDK path, use: flutter config --jdk-dir="path/to/jdk".
    • Java version OpenJDK Runtime Environment (build 21.0.10+-14961533-b1163.108)
    • All Android licenses accepted.

    [√] Chrome - develop for the web [96ms]
    • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

    [√] Visual Studio - develop Windows apps (Visual Studio Enterprise 2022 17.14.35 (June 2026)) [95ms]
    • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Enterprise
    • Visual Studio Enterprise 2022 version 17.14.37411.7
    • Windows 10 SDK version 10.0.19041.0

    [√] Connected device (3 available) [198ms]
    • Windows (desktop) • windows • windows-x64 • Microsoft Windows [版本 10.0.19044.7548]
    • Chrome (web) • chrome • web-javascript • Google Chrome 131.0.6778.205
    • Edge (web) • edge • web-javascript • Microsoft Edge 150.0.4078.83

    [√] Network resources [11.9s]
    • All expected network resources are available.

    • No issues found!

  6. KuiperBelt-LAW commented on Jul 23, 2026

    @KuiperBelt-LAW

    in my picture, the curve in fl_chart has the same result.

  7. added
    P1High-priority issues at the top of the work list
    on Jul 27, 2026
  8. gaaclarke commented on Jul 27, 2026

    @gaaclarke
    Member

    @b-luk can you take a peek at this, please?

  9. b-luk commented on Jul 28, 2026

    @b-luk
    Contributor

    The issue with square corners is #189807 and should be fixed.

    The jaggedness is a separate issue. I can reproduce it. It seems to be related specifically to UberSDF rendering on Windows. It is not specific to BoxDecoration or rounded rectangles. It seems like all shapes rendered with UberSDF on Windows do not get antialiased.

    Here's a demo app that renders a circle, a rounded rectangle, a normal rectangle, and a rotated rectangle.

    demo
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return InteractiveViewer(
          maxScale: 10,
          child: Container(
            color: Colors.black,
            child: CustomPaint(painter: TestPainter()),
          ),
        );
      }
    }
    
    class TestPainter extends CustomPainter {
      @override
      void paint(Canvas canvas, Size size) {
        // circle
        canvas.drawCircle(Offset(50, 50), 20, Paint()..color = Colors.white);
    
        // rounded rect
        canvas.translate(0, 100);
        canvas.drawRRect(
          RRect.fromRectAndRadius(Rect.fromLTWH(20, 20, 50, 50), .circular(10)),
          Paint()..color = Colors.white,
        );
    
        // rect
        canvas.translate(0, 100);
        canvas.drawRect(
          Rect.fromLTWH(20, 20, 50, 50),
          Paint()..color = Colors.white,
        );
    
        // rotated rect
        canvas.save();
        canvas.translate(100, 0);
        canvas.rotate(0.3);
        canvas.drawRect(
          Rect.fromLTWH(20, 20, 50, 50),
          Paint()..color = Colors.white,
        );
        canvas.restore();
      }
    
      @override
      bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
    }

    Windows with OpenGLES and SDFs enabled

    By default, Windows uses Impeller with OpenGLES and UberSDF enabled:
    [IMPORTANT:flutter/shell/platform/embedder/embedder_surface_gl_impeller.cc(127)] Using the Impeller rendering backend (OpenGLESSDF).

    Results 400% zoom
    Image Image

    It seems like antialiasing for these shapes is disabled entirely. The pixels along the edge of the shapes are either fully opaque or fully transparent.

    Linux with OpenGLES and UberSDF

    Linux, like Windows, by default uses OpenGLES with UberSDF enabled:

    But unlike Windows, UberSDF on Linux has proper antialiasing.

    Results 400% zoom
    Image Image

    Windows and Linux with OpenGLES and UberSDF disabled

    This example is not directly related to the issue. But for comparison, here is rendering with UberSDF disabled. This usees a hacked local engine to always have use_sdfs=false.
    [IMPORTANT:flutter/shell/platform/embedder/embedder_surface_gl_impeller.cc(129)] Using the Impeller rendering backend (OpenGLES).

    Results 400% zoom
    Image Image

    This specific example shows Windows, but Linux has the same behavior.

    Circle has antialiasing. When UberSDF is disabled, Impeller's canvas::DrawCircle uses a non-UberSDF, separate SDF-based circle shader:

    if (AttemptDrawAntialiasedCircle(center, radius, paint)) {

    This uses the non-UberSDF circle.frag SDF shader.

    This circle SDF shader works both on Linux and on Windows. It is surprising that it works on Windows when UberSDF seems broken on Windows.

    The other shapes (the rounded rectangle and rotated rectangle) do not use SDFs and are rendered with tessellation. They do not have any antialiasing, both on Windows and Linux.

  10. github-actions commented on Aug 15, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  11. locked as resolved and limited conversation to collaborators on Aug 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P1High-priority issues at the top of the work listc: renderingUI glitches reported at the engine/skia or impeller rendering levele: impellerImpeller rendering backend issues and features requestsplatform-windowsBuilding on or for Windows specificallyteam-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