Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 06944ac

Browse files
[Impeller] make strokes slightly lighter. (#53067)
We can set the minimum stroke width to 0.5 to guarantee at least one hit of 4x MSAA coverage. This doesn't fix stroke fidelity issues but it does make it a bit better. flutter/flutter#144313
1 parent dd019f6 commit 06944ac

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

impeller/aiks/aiks_path_unittests.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ TEST_P(AiksTest, CanRenderThickCurvedStrokes) {
4848
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
4949
}
5050

51+
TEST_P(AiksTest, CanRenderThinCurvedStrokes) {
52+
Canvas canvas;
53+
Paint paint;
54+
paint.color = Color::Red();
55+
// Impeller doesn't support hairlines yet, but size this guarantees
56+
// the smallest possible stroke width.
57+
paint.stroke_width = 0.01;
58+
paint.style = Paint::Style::kStroke;
59+
canvas.DrawPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath(), paint);
60+
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
61+
}
62+
5163
TEST_P(AiksTest, CanRenderStrokePathThatEndsAtSharpTurn) {
5264
Canvas canvas;
5365

impeller/entity/geometry/stroke_path_geometry.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ using VS = SolidFillVertexShader;
1515

1616
namespace {
1717

18+
/// @brief The minimum stroke size can be less than one physical pixel because
19+
/// of MSAA, but no less that half a physical pixel otherwise we might
20+
/// not hit one of the sample positions.
21+
static constexpr Scalar kMinStrokeSizeMSAA = 0.5f;
22+
23+
static constexpr Scalar kMinStrokeSize = 1.0f;
24+
1825
template <typename VertexWriter>
1926
using CapProc = std::function<void(VertexWriter& vtx_builder,
2027
const Point& position,
@@ -530,7 +537,10 @@ GeometryResult StrokePathGeometry::GetPositionBuffer(
530537
return {};
531538
}
532539

533-
Scalar min_size = 1.0f / sqrt(std::abs(determinant));
540+
Scalar min_size =
541+
(pass.GetSampleCount() == SampleCount::kCount4 ? kMinStrokeSizeMSAA
542+
: kMinStrokeSize) /
543+
sqrt(std::abs(determinant));
534544
Scalar stroke_width = std::max(stroke_width_, min_size);
535545

536546
auto& host_buffer = renderer.GetTransientsBuffer();
@@ -584,7 +594,8 @@ std::optional<Rect> StrokePathGeometry::GetCoverage(
584594
if (determinant == 0) {
585595
return std::nullopt;
586596
}
587-
Scalar min_size = 1.0f / sqrt(std::abs(determinant));
597+
// Use the most conervative coverage setting.
598+
Scalar min_size = kMinStrokeSize / sqrt(std::abs(determinant));
588599
max_radius *= std::max(stroke_width_, min_size);
589600
return path_bounds->Expand(max_radius).TransformBounds(transform);
590601
}

testing/impeller_golden_tests_output.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,9 @@ impeller_Play_AiksTest_CanRenderTextWithLargePerspectiveTransform_Vulkan.png
460460
impeller_Play_AiksTest_CanRenderThickCurvedStrokes_Metal.png
461461
impeller_Play_AiksTest_CanRenderThickCurvedStrokes_OpenGLES.png
462462
impeller_Play_AiksTest_CanRenderThickCurvedStrokes_Vulkan.png
463+
impeller_Play_AiksTest_CanRenderThinCurvedStrokes_Metal.png
464+
impeller_Play_AiksTest_CanRenderThinCurvedStrokes_OpenGLES.png
465+
impeller_Play_AiksTest_CanRenderThinCurvedStrokes_Vulkan.png
463466
impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_Metal.png
464467
impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_OpenGLES.png
465468
impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_Vulkan.png

0 commit comments

Comments
 (0)