Skip to content

[Impeller] Fast arc stroke generator can overdraw when caps intersect #178746

@b-luk

Description

@b-luk

Steps to reproduce

Draw a circular stroked arc with a transparent color. Use square stroke caps, and use a high sweep angle and stroke width so that the two square caps intersect.

This was an issue discovered and discussed with @flar. The fast arc stroke tessellation introduced in #169402 can draw overlapping geometry. The fast arc stroke tessellation does not take overdraw into account, causing incorrect coloring issues when used with transparent colors. This is similar to #174579.

Currently this overlap can only happen when using square caps. After #169400 is fixed, this will also happen with round caps.

This can be fixed by using GeometryResult::Mode::kPreventOverdraw, or by not using the fast arc stroke geometry for arcs with overlapping caps. We may want to performance comparisons for these two approaches in order to decide which one to use.

Expected results

Overlapping caps should be the same color as the rest of the arc.

Image

Actual results

Overlapping caps get overdrawn. The color is composited multiple times, causing a color mismatch with the rest of the arc.

Image

Code sample

Code sample
import 'dart:math' as math show pi;

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: CustomPaint(painter: TestPainter()),
    );
  }
}

class TestPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawArc(
      Rect.fromCircle(center: size.center(Offset.zero), radius: 50),
      0,
      1.5 * math.pi,
      false,
      Paint()
        ..color = Colors.blue.withAlpha(127)
        ..style = PaintingStyle.stroke
        ..strokeWidth = 80
        ..strokeCap = StrokeCap.square,
    );
  }

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

Screenshots or Video

See screenshots above.

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, 3.39.0-1.0.pre-181, on macOS 15.7.1 24G231 darwin-arm64, locale en)
[✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.3)
[✓] Chrome - develop for the web
[✓] Connected device (4 available)
[✓] Network resources

• No issues found!

Metadata

Metadata

Assignees

Labels

P1High-priority issues at the top of the work liste: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.team-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