Skip to content

Antialiasing behaviour when same-colour  #14288

Description

@radzish

Latest status update: #14288 (comment); some work around suggestions: #14288 (comment)


Steps to Reproduce

Following source code:

import 'package:flutter/material.dart';

const Color color = const Color.fromARGB(255, 100, 100, 100);

void main() =>
    runApp(
      new Container(
        color: const Color.fromARGB(255, 0, 0, 0),
        child: new Row(
          mainAxisAlignment: MainAxisAlignment.end,
          textDirection: TextDirection.ltr,
          children: [
            new Expanded(
              child: new Container(
                color: color,
              ),
            ),
            new Expanded(
              child: new Container(
                color: color,
              ),
            ),
            new Expanded(
              child: new Container(
                color: color,
              ),
            ),
            new Expanded(
              child: new Container(
                color: color,
              ),
            ),
            new Expanded(
              child: new Container(
                color: color,
              ),
            ),
            new Expanded(
              child: new Container(
                color: color,
              ),
            ),
            new Expanded(
              child: new Container(
                color: color,
              ),
            ),
          ],
        ),
      ),
    );

produces following result:

Looks like background of the container is popping out and we see vertical lines. That should not be the case as all children of the row are Expanded and thus should fill the whole area.
If we remove one child lines are gone.

Logs

Launching lib/main.dart on Android SDK built for x86 in debug mode...
Initializing gradle...
Resolving dependencies...
Running 'gradlew assembleDebug'...
Built build/app/outputs/apk/app-debug.apk (22.4MB).
I/FlutterActivityDelegate( 8398): onResume setting current activity to this
D/EGL_emulation( 8398): eglMakeCurrent: 0xaad2c640: ver 3 1 (tinfo 0xa057c5b0)
E/eglCodecCommon( 8398): glUtilsParamSize: unknow param 0x000082da
E/eglCodecCommon( 8398): glUtilsParamSize: unknow param 0x000082da
E/eglCodecCommon( 8398): glUtilsParamSize: unknow param 0x00008cdf
E/eglCodecCommon( 8398): glUtilsParamSize: unknow param 0x00008cdf
E/eglCodecCommon( 8398): glUtilsParamSize: unknow param 0x00008824
E/eglCodecCommon( 8398): glUtilsParamSize: unknow param 0x00008824
D/        ( 8398): HostConnection::get() New Host Connection established 0xa31a3640, tid 8416
D/EGL_emulation( 8398): eglMakeCurrent: 0xaad2c640: ver 3 1 (tinfo 0xa3183790)
D/EGL_emulation( 8398): eglMakeCurrent: 0xaad2c760: ver 3 1 (tinfo 0xa057cc10)
Syncing files to device Android SDK built for x86...

Flutter Doctor

[✓] Flutter (on Linux, locale en_US.UTF-8, channel master)
    • Flutter version unknown at <path_to_flutter>
    • Framework revision 5ae770345a (3 days ago), 2018-01-23 13:46:14 -0800
    • Engine revision 171d032f86
    • Tools Dart version 2.0.0-dev.16.0
    • Engine Dart version 2.0.0-edge.93d8c9fe2a2c22dc95ec85866af108cfab71ad06

[✓] Android toolchain - develop for Android devices (Android SDK 27.0.3)
    • Android SDK at <path_to_android>
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-27, build-tools 27.0.3
    • ANDROID_HOME = <path_to_android>
    • Java binary at: <path_to_android-studio>/jre/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-915-b01)

[✓] Android Studio (version 3.0)
    • Android Studio at <path_to_android-studio>
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-915-b01)

[✓] Connected devices
    • Android SDK built for x86 • emulator-5554 • android-x86 • Android 8.1.0 (API 27) (emulator)

Activity

  1. radzish commented on Jan 26, 2018

    @radzish
    Author

    Another example (I believe it is somehow related: )

    import 'package:flutter/material.dart';
    
    const Color grey = const Color.fromARGB(255, 100, 100, 100);
    const Color black = const Color.fromARGB(255, 0, 0, 0);
    
    void main() =>
        runApp(
          new Container(
            color: grey,
            child: new Center(
              child: new Container(
                width: 151.0,
                height: 151.0,
                color: black,
                child: new Container(
                  color: grey,
                ),
              ),
            ),
          ),
        );

    We should not see border here. If widht/height are changed to 150.0, square is gone.

  2. Hixie commented on Jan 29, 2018

    @Hixie
    Contributor

    This is normal behaviour. What's happening is that the boxes are not quite aligned with pixel boundaries, so there's some anti-aliasing happening on the boundaries, which involves transparency, which means that for those pixels the two grays are overlapping and looking darker.

    As a general rule when doing anti-aliasing you want to avoid putting identically-coloured boxes adjacent or over each other unless you can guarantee physical pixel alignment.

    Alternatively, you can use saveLayer (or RepaintBoundary) to cause a bunch of paint operations to get merged into one and composited as one. Not sure that that would help in these cases specifically but it is a tool that can be useful in this kind of situation.

  3. radzish commented on Jan 30, 2018

    @radzish
    Author

    This is not boxes overlapping, but rather spare space between boxes, so color of background is popping up. I was changing background to different color and this color was popping out.

  4. radzish commented on Feb 22, 2018

    @radzish
    Author

    Root cause is that boxes can not be aligned with physical pixels. I would not call it "normal", I would rather call it "expected".
    On android similar (semantically) case is handled properly:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="#000000"
        tools:context="com.radzish.android_lines_bug.MainActivity">
    
        <FrameLayout
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="#646464"
            android:layout_height="match_parent"/>
    
        <FrameLayout
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="#646464"
            android:layout_height="match_parent"/>
    
        <FrameLayout
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="#646464"
            android:layout_height="match_parent"/>
    
        <FrameLayout
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="#646464"
            android:layout_height="match_parent"/>
    
        <FrameLayout
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="#646464"
            android:layout_height="match_parent"/>
    
        <FrameLayout
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="#646464"
            android:layout_height="match_parent"/>
    
        <FrameLayout
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="#646464"
            android:layout_height="match_parent"/>
    
    </LinearLayout>

    So I think flutter should improve in this case.
    The only workaround I found for me at the moment is sizing children manually like this:

        int CHILDREN_COUNT = 7;
        List<Widget> children = new List(CHILDREN_COUNT);
    
        MediaQueryData mediaQueryData = MediaQuery.of(context);
        int physicalWidth = (mediaQueryData.size.width * mediaQueryData.devicePixelRatio).floor();
    
        for (int i = 0, pixelsLeft = physicalWidth; i < CHILDREN_COUNT; i++) {
          int columnWidth = (pixelsLeft / (CHILDREN_COUNT - i)).floor();
    
          children[i] = new Container(
            width: columnWidth / mediaQueryData.devicePixelRatio,
            color: color,
          );
    
          pixelsLeft -= columnWidth;
        }
    
  5. changed the title [-]Expanded elements not taking the whole are of their parent[/-] [+]Expanded elements not taking the whole area of their parent[/+] on May 29, 2018
  6. changed the title [-]Expanded elements not taking the whole area of their parent[/-] [+]Document the issue of antialiasing when same-colour blocks abut, and some workarounds[/+] on May 29, 2018
  7. added this to the milestone on May 29, 2018
  8. changed the title [-]Document the issue of antialiasing when same-colour blocks abut, and some workarounds[/-] [+]Document the issue of antialiasing when same-colour blocks abut, and some workarounds (API docs, FAQ)[/+] on May 29, 2018
  9. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    and removed
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Dec 4, 2018
  10. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Dec 17, 2018
  11. added
    customer: crowdAffects or could affect many people, though not necessarily a specific customer.
    on Dec 28, 2018
  12. 130 remaining items

  13. Amir-P commented on Jun 12, 2024

    @Amir-P
    Contributor

    Just wanted to share another case with you (#150035). It happens with Impeller on iOS too.

    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(
          title: 'Flutter Demo',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(primarySwatch: Colors.blue),
          home: const MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      const MyHomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Stack(
            children: [
              Positioned.fill(child: ColoredBox(color: Colors.blue)),
              Center(
                child: SizedBox(
                  width: 200,
                  height: 200,
                  child: Stack(
                    children: [
                      Positioned.fill(child: ColoredBox(color: Colors.red)),
                      Positioned.fill(
                        child: ColoredBox(color: Colors.blue),
                      )
                    ],
                  ),
                ),
              ),
            ],
          ),
        );
      }
    }
  14. ulisseshen commented on Jul 14, 2024

    @ulisseshen
    Contributor

    Is it a skia or a Flutter issue?

  15. LvtLvt commented on Jul 18, 2024

    @LvtLvt

    Hello,
    I'm dealing with the same problems as mention above, thin white lines between widgets (rows in my case), when rendering to web. It looks like an anti-alias or not-pixel-perfect issue, also as already mentioned above.
    Have I understood it correctly that there is no proper/native solution to this, and the best option is to use pixel_snap?
    UPDATE: I also tried building/running for Linux desktop, and I get the same white lines. But using a Scaffold with backgroundColor works as a workaround, which happens to be usable in this case.

    Also you may try space_fixer https://pub.dev/packages/space_fixer

    Example:

              Container(
                width: MediaQuery.of(context).size.width,
                height: 50,
                color: Colors.black,
              ),
              SpaceFixerHorizontalLine(
                context: context,
                overflowHeight: 3,
                overflowColor: Colors.black,
              ),
              Container(
                width: MediaQuery.of(context).size.width,
                height: 50,
                color: Colors.black,
              ),

    https://github.com/erlangparasu/space_fixer/blob/e3a5b8f158f64507a486c1f8904431cb8c6ce773/example/example1.dart#L59

    You can use this widget as a divider in the list

    thanks to you, I was able to easily solve the problem without much overhead. thank you so much

  16. officialismailshah commented on Jul 28, 2024

    @officialismailshah
  17. devnta commented on Oct 15, 2024

    @devnta

    Unbelievable, this issue has existed for a few years?
    Any official solution on this?

  18. spydon commented on Oct 21, 2024

    @spydon
    Contributor

    This issue can be very apparent when you're making games with Flutter (and Flame), and the curious thing is that nowadays the issue is usually worse with Impeller than it is with Skia.
    image

  19. Mik77o commented on Nov 21, 2024

    @Mik77o

    The same issue is noticed on Flutter Web (3.24.4) for ListView (mostly while scrolling).

  20. NashIlli commented on Feb 12, 2025

    @NashIlli

    +1

  21. ThomasDevApps commented on Mar 9, 2025

    @ThomasDevApps

    I have the same problem using SliverAppBar (I can give the code to reproduce the problem if needed).

  22. davidhicks980 commented on May 16, 2025

    @davidhicks980
    Contributor

    There are a lot of comments here so I apologize if I'm duplicating another solution. Also, this won't fix the problem for everyone.

    There is the option of disabling anti-aliasing:

    AliasedBoxDecoration
    // Copyright 2014 The Flutter Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    
    import 'package:flutter/rendering.dart';
    
    class AliasedBoxDecoration extends BoxDecoration {
      const AliasedBoxDecoration({
        super.color,
        super.image,
        super.border,
        super.borderRadius,
        super.boxShadow,
        super.gradient,
        super.backgroundBlendMode,
        super.shape = BoxShape.rectangle,
      });
      @override
      BoxPainter createBoxPainter([VoidCallback? onChanged]) {
        assert(onChanged != null || image == null);
        return _AliasedBoxDecorationPainter(this, onChanged);
      }
    }
    
    class _AliasedBoxDecorationPainter extends BoxPainter {
      _AliasedBoxDecorationPainter(this._decoration, super.onChanged);
    
      final AliasedBoxDecoration _decoration;
    
      Paint? _cachedBackgroundPaint;
      Rect? _rectForCachedBackgroundPaint;
      Paint _getBackgroundPaint(Rect rect, TextDirection? textDirection) {
        assert(_decoration.gradient != null || _rectForCachedBackgroundPaint == null);
    
        if (_cachedBackgroundPaint == null ||
            (_decoration.gradient != null && _rectForCachedBackgroundPaint != rect)) {
          final Paint paint = Paint();
          if (_decoration.backgroundBlendMode != null) {
            paint.blendMode = _decoration.backgroundBlendMode!;
          }
          if (_decoration.color != null) {
            paint.color = _decoration.color!;
          }
          if (_decoration.gradient != null) {
            paint.shader = _decoration.gradient!.createShader(rect, textDirection: textDirection);
            _rectForCachedBackgroundPaint = rect;
          }
          _cachedBackgroundPaint = paint..isAntiAlias = false;
        }
    
        return _cachedBackgroundPaint!;
      }
    
      void _paintBox(Canvas canvas, Rect rect, Paint paint, TextDirection? textDirection) {
        switch (_decoration.shape) {
          case BoxShape.circle:
            assert(_decoration.borderRadius == null);
            final Offset center = rect.center;
            final double radius = rect.shortestSide / 2.0;
            canvas.drawCircle(center, radius, paint);
          case BoxShape.rectangle:
            if (_decoration.borderRadius == null || _decoration.borderRadius == BorderRadius.zero) {
              canvas.drawRect(rect, paint);
            } else {
              canvas.drawRRect(_decoration.borderRadius!.resolve(textDirection).toRRect(rect), paint);
            }
        }
      }
    
      void _paintShadows(Canvas canvas, Rect rect, TextDirection? textDirection) {
        if (_decoration.boxShadow == null) {
          return;
        }
        for (final BoxShadow boxShadow in _decoration.boxShadow!) {
          final Paint paint = boxShadow.toPaint()..isAntiAlias = false;
          final Rect bounds = rect.shift(boxShadow.offset).inflate(boxShadow.spreadRadius);
          assert(() {
            if (debugDisableShadows && boxShadow.blurStyle == BlurStyle.outer) {
              canvas.save();
              canvas.clipRect(bounds);
            }
            return true;
          }());
          _paintBox(canvas, bounds, paint, textDirection);
          assert(() {
            if (debugDisableShadows && boxShadow.blurStyle == BlurStyle.outer) {
              canvas.restore();
            }
            return true;
          }());
        }
      }
    
      void _paintBackgroundColor(Canvas canvas, Rect rect, TextDirection? textDirection) {
        if (_decoration.color != null || _decoration.gradient != null) {
          // When border is filled, the rect is reduced to avoid anti-aliasing
          // rounding error leaking the background color around the clipped shape.
          final Rect adjustedRect = _adjustedRectOnOutlinedBorder(rect, textDirection);
          _paintBox(canvas, adjustedRect, _getBackgroundPaint(rect, textDirection), textDirection);
        }
      }
    
      double _calculateAdjustedSide(BorderSide side) {
        if (side.color.alpha == 255 && side.style == BorderStyle.solid) {
          return side.strokeInset;
        }
        return 0;
      }
    
      Rect _adjustedRectOnOutlinedBorder(Rect rect, TextDirection? textDirection) {
        if (_decoration.border == null) {
          return rect;
        }
    
        if (_decoration.border is Border) {
          final Border border = _decoration.border! as Border;
    
          final EdgeInsets insets = EdgeInsets.fromLTRB(
                _calculateAdjustedSide(border.left),
                _calculateAdjustedSide(border.top),
                _calculateAdjustedSide(border.right),
                _calculateAdjustedSide(border.bottom),
              ) /
              2;
    
          return Rect.fromLTRB(
            rect.left + insets.left,
            rect.top + insets.top,
            rect.right - insets.right,
            rect.bottom - insets.bottom,
          );
        } else if (_decoration.border is BorderDirectional && textDirection != null) {
          final BorderDirectional border = _decoration.border! as BorderDirectional;
          final BorderSide leftSide = textDirection == TextDirection.rtl ? border.end : border.start;
          final BorderSide rightSide = textDirection == TextDirection.rtl ? border.start : border.end;
    
          final EdgeInsets insets = EdgeInsets.fromLTRB(
                _calculateAdjustedSide(leftSide),
                _calculateAdjustedSide(border.top),
                _calculateAdjustedSide(rightSide),
                _calculateAdjustedSide(border.bottom),
              ) /
              2;
    
          return Rect.fromLTRB(
            rect.left + insets.left,
            rect.top + insets.top,
            rect.right - insets.right,
            rect.bottom - insets.bottom,
          );
        }
        return rect;
      }
    
      DecorationImagePainter? _imagePainter;
      void _paintBackgroundImage(Canvas canvas, Rect rect, ImageConfiguration configuration) {
        if (_decoration.image == null) {
          return;
        }
        _imagePainter ??= _decoration.image!.createPainter(onChanged!);
        Path? clipPath;
        switch (_decoration.shape) {
          case BoxShape.circle:
            assert(_decoration.borderRadius == null);
            final Offset center = rect.center;
            final double radius = rect.shortestSide / 2.0;
            final Rect square = Rect.fromCircle(center: center, radius: radius);
            clipPath = Path()..addOval(square);
          case BoxShape.rectangle:
            if (_decoration.borderRadius != null) {
              clipPath = Path()
                ..addRRect(
                  _decoration.borderRadius!.resolve(configuration.textDirection).toRRect(rect),
                );
            }
        }
        _imagePainter!.paint(canvas, rect, clipPath, configuration);
      }
    
      @override
      void dispose() {
        _imagePainter?.dispose();
        super.dispose();
      }
    
      @override
      void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
        assert(configuration.size != null);
        final Rect rect = offset & configuration.size!;
        final TextDirection? textDirection = configuration.textDirection;
        _paintShadows(canvas, rect, textDirection);
        _paintBackgroundColor(canvas, rect, textDirection);
        _paintBackgroundImage(canvas, rect, configuration);
        _decoration.border?.paint(
          canvas,
          rect,
          shape: _decoration.shape,
          borderRadius: _decoration.borderRadius?.resolve(textDirection),
          textDirection: configuration.textDirection,
        );
      }
    
      @override
      String toString() {
        return 'BoxPainter for $_decoration';
      }
    }
    
    

    Using this solution fixes the original problem. I'm not sure about others.

    Image
    ColoredBox(
            color: const Color.fromARGB(255, 0, 0, 0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              textDirection: TextDirection.ltr,
              children: <Widget>[
                Expanded(
                  child: Container(
                    decoration: const AliasedBoxDecoration(
                      color: color,
                    ),
                  ),
                ),
                Expanded(
                  child: Container(
                    decoration: const AliasedBoxDecoration(
                      color: color,
                    ),
                  ),
                ),
          ]))
  23. zhujunjieyuewen commented on Jun 18, 2025

    @zhujunjieyuewen

    On my Pixel 9 Pro device (with a devicePixelRatio of 2.25), setting the ListView item height to 200.0 results in no gaps appearing between items during scrolling. However, setting the height to 210.0 causes noticeable gaps to appear between items during scrolling.

    After reading the previous comments, I understand the cause of this phenomenon: 200 * 2.25 = 450 (an integer number of physical pixels), while 210 * 2.25 = 472.5 (a non-integer number of physical pixels).

    As a framework user, however, I don't believe this is something I should need to be concerned about. What I expect is the ability to freely set the item height to any desired value, and for the framework to automatically handle the issue where that height translates to a non-integer number of physical pixels. Whether the framework rounds down (floor), rounds up (ceil), or uses any other appropriate conversion method is acceptable to me—as long as the outcome ensures there are no gaps between items.

    After all, the page I'm currently working on is a comic reader page. Seeing gaps appear between visually continuous images is genuinely disruptive to the reading experience.

    Here is my demo code:

    Image

    The resulting behavior:

    41fb3ddf502ef46201437cdb54ddea38.mp4

    The appearance issue on the comic reader page matches the screenshot shown in a previous comment #14288 (comment).

  24. orestesgaolin commented on Jul 17, 2025

    @orestesgaolin
    Contributor

    I'm having the same issue now when implementing a HR chart using CustomPaint. Putting two paths with the same color back to back where right x coordinate coincides with left x coordinate results with quite ugly look.

    Having to figure out how to snap path to physical pixels in such case is huge annoyance for a developer.

    Image

    Edit

    I was able to workaround this issue with following (inspired by package:pixel_snap)

    1. Painter needs to be aware of the devicePixelRatio
    2. Make sure to round all the Offsets and Paths to nearest pixel (see pseudo code below)
    3. Your Paint needs to skip antialiasing
    class MyPainter extends CustomPainter {
      MyPainter({
        required this.devicePixelRatio,
      });
    
      final double devicePixelRatio;
    
      @override
      void paint(Canvas canvas, Size size) {
        // painter logic
        points.add(OffsetSnappedF(x, y, devicePixelRatio));
        final path = Path()..addPolygon(points, true);
        
        final shader = LinearGradient(
          colors: awakeGradientColors,
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
        ).createShader(
          Rect.fromLTWH(0, minY, size.width, size.height - minY),
        );
    
        canvas.drawPath(
          path,
          Paint()
            ..shader = shader
            ..isAntiAlias = false,
        );
      }
    }
    
    class OffsetSnappedF extends Offset {
      OffsetSnappedF(this.dx, this.dy, this.devicePixelRatio) : super(dx.snappedF(devicePixelRatio), dy);
    
      @override
      final double dx;
      @override
      final double dy;
      final double devicePixelRatio;
    }
    
    extension on double {
      double snappedF(double devicePixelRatio) {
        return (this * devicePixelRatio - 0.05).round() / devicePixelRatio;
      }
    }
    
    extension on Path {
      void moveToSnapped(double x, double y, double devicePixelRatio) {
        moveTo(x.snappedF(devicePixelRatio), y);
      }
    
      void lineToSnapped(double x, double y, double devicePixelRatio) {
        lineTo(x.snappedF(devicePixelRatio), y);
      }
    }
  25. AwaisQazii commented on Oct 29, 2025

    @AwaisQazii

    My workaround on this issue is: #97054 (comment)

    I was able to resolve this issue by setting:

    resizeToAvoidBottomInset: false,

    and add padding to singlechildscrollview

    SingleChildScrollView(
    padding: EdgeInsets.only(
    bottom: MediaQuery.viewInsetsOf(context).bottom + 50,
    ),

    then adding scrollPadding to the TextField:

    scrollPadding: EdgeInsets.only(
    bottom: MediaQuery.viewInsetsOf(context).bottom + 50,
    ),

    For context, my layout structure looks like this:

    Container
    └─ background color: red
    └─ Scaffold
    ├─ backgroundColor: transparent
    ├─ resizeToAvoidBottomInset: false
    └─ body:
    └─Single ChildScrollView
    padding: EdgeInsets.only(
    bottom: MediaQuery.viewInsetsOf(context).bottom + 50,
    ),
    └─ TextField
    └─ scrollPadding:
    EdgeInsets.only(
    bottom: MediaQuery.viewInsetsOf(context).bottom + 50,
    )

  26. aidarbye commented on Dec 9, 2025

    @aidarbye
  27. lifelikejuly commented on Jan 30, 2026

    @lifelikejuly
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projecta: gamedevIssues related to game development with Flutterc: renderingUI glitches reported at the engine/skia or impeller rendering levelcustomer: crowdAffects or could affect many people, though not necessarily a specific customer.engineflutter/engine related. See also e: labels.found in release: 3.3Found to occur in 3.3found in release: 3.4Found to occur in 3.4frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-engineOwned by Engine teamtriaged-engineTriaged by Engine teamworkaround availableThere is a workaround available to overcome the issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions