diff --git a/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc b/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc index 953f193be9..e902f22804 100644 --- a/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc +++ b/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc @@ -461,6 +461,45 @@ TEST_P(AiksTest, CanRenderClips) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +TEST_P(AiksTest, FatStrokeArc) { + DlScalar stroke_width = 300; + DlScalar aspect = 1.0; + DlScalar start_angle = 0; + DlScalar end_angle = 90; + auto callback = [&]() -> sk_sp { + if (AiksTest::ImGuiBegin("Controls", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::SliderFloat("Stroke Width", &stroke_width, 1, 300); + ImGui::SliderFloat("Aspect", &aspect, 0.5, 2.0); + ImGui::SliderFloat("Start Angle", &start_angle, 0, 360); + ImGui::SliderFloat("End Angle", &end_angle, 0, 360); + ImGui::End(); + } + + DisplayListBuilder builder; + DlPaint grey_paint; + grey_paint.setColor(DlColor(0xff111111)); + builder.DrawPaint(grey_paint); + + DlPaint white_paint; + white_paint.setColor(DlColor::kWhite()); + white_paint.setStrokeWidth(stroke_width); + white_paint.setDrawStyle(DlDrawStyle::kStroke); + DlPaint red_paint; + red_paint.setColor(DlColor::kRed()); + + Rect rect = Rect::MakeXYWH(100, 100, 100, aspect * 100); + builder.DrawRect(rect, red_paint); + builder.DrawArc(rect, start_angle, end_angle, + /*useCenter=*/false, white_paint); + DlScalar frontier = rect.GetRight() + stroke_width / 2.0; + builder.DrawLine(Point(frontier, 0), Point(frontier, 150), red_paint); + + return builder.Build(); + }; + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + TEST_P(AiksTest, CanRenderOverlappingMultiContourPath) { DisplayListBuilder builder; diff --git a/engine/src/flutter/impeller/display_list/dl_dispatcher.cc b/engine/src/flutter/impeller/display_list/dl_dispatcher.cc index 487d2a8551..6d39f5719c 100644 --- a/engine/src/flutter/impeller/display_list/dl_dispatcher.cc +++ b/engine/src/flutter/impeller/display_list/dl_dispatcher.cc @@ -642,10 +642,26 @@ void DlDispatcherBase::drawArc(const DlRect& oval_bounds, bool use_center) { AUTO_DEPTH_WATCHER(1u); - PathBuilder builder; - builder.AddArc(oval_bounds, Degrees(start_degrees), Degrees(sweep_degrees), - use_center); - GetCanvas().DrawPath(builder.TakePath(), paint_); + if (paint_.stroke_width > + std::max(oval_bounds.GetWidth(), oval_bounds.GetHeight())) { + // This is a special case for rendering arcs whose stroke width is so large + // you are effectively drawing a sector of a circle. + // https://github.com/flutter/flutter/issues/158567 + DlRect expanded_rect = oval_bounds.Expand(Size(paint_.stroke_width / 2)); + PathBuilder builder; + Paint fill_paint = paint_; + fill_paint.style = Paint::Style::kFill; + fill_paint.stroke_width = 1; + builder.AddArc(expanded_rect, Degrees(start_degrees), + Degrees(sweep_degrees), + /*use_center=*/true); + GetCanvas().DrawPath(builder.TakePath(), fill_paint); + } else { + PathBuilder builder; + builder.AddArc(oval_bounds, Degrees(start_degrees), Degrees(sweep_degrees), + use_center); + GetCanvas().DrawPath(builder.TakePath(), paint_); + } } // |flutter::DlOpReceiver| diff --git a/engine/src/flutter/testing/impeller_golden_tests_output.txt b/engine/src/flutter/testing/impeller_golden_tests_output.txt index 7a7372d3fb..0ac59638b0 100644 --- a/engine/src/flutter/testing/impeller_golden_tests_output.txt +++ b/engine/src/flutter/testing/impeller_golden_tests_output.txt @@ -690,6 +690,9 @@ impeller_Play_AiksTest_FastGradientTestVerticalReversed_Vulkan.png impeller_Play_AiksTest_FastGradientTestVertical_Metal.png impeller_Play_AiksTest_FastGradientTestVertical_OpenGLES.png impeller_Play_AiksTest_FastGradientTestVertical_Vulkan.png +impeller_Play_AiksTest_FatStrokeArc_Metal.png +impeller_Play_AiksTest_FatStrokeArc_OpenGLES.png +impeller_Play_AiksTest_FatStrokeArc_Vulkan.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_Metal.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_Vulkan.png