[Impeller] make strokes slightly lighter. (flutter/engine#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.

https://github.com/flutter/flutter/issues/144313
This commit is contained in:
Jonah Williams 2024-05-28 14:04:21 -07:00 committed by GitHub
parent ad5ba74b0d
commit eae27f210b
3 changed files with 28 additions and 2 deletions

View File

@ -48,6 +48,18 @@ TEST_P(AiksTest, CanRenderThickCurvedStrokes) {
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}
TEST_P(AiksTest, CanRenderThinCurvedStrokes) {
Canvas canvas;
Paint paint;
paint.color = Color::Red();
// Impeller doesn't support hairlines yet, but size this guarantees
// the smallest possible stroke width.
paint.stroke_width = 0.01;
paint.style = Paint::Style::kStroke;
canvas.DrawPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath(), paint);
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}
TEST_P(AiksTest, CanRenderStrokePathThatEndsAtSharpTurn) {
Canvas canvas;

View File

@ -15,6 +15,13 @@ using VS = SolidFillVertexShader;
namespace {
/// @brief The minimum stroke size can be less than one physical pixel because
/// of MSAA, but no less that half a physical pixel otherwise we might
/// not hit one of the sample positions.
static constexpr Scalar kMinStrokeSizeMSAA = 0.5f;
static constexpr Scalar kMinStrokeSize = 1.0f;
template <typename VertexWriter>
using CapProc = std::function<void(VertexWriter& vtx_builder,
const Point& position,
@ -530,7 +537,10 @@ GeometryResult StrokePathGeometry::GetPositionBuffer(
return {};
}
Scalar min_size = 1.0f / sqrt(std::abs(determinant));
Scalar min_size =
(pass.GetSampleCount() == SampleCount::kCount4 ? kMinStrokeSizeMSAA
: kMinStrokeSize) /
sqrt(std::abs(determinant));
Scalar stroke_width = std::max(stroke_width_, min_size);
auto& host_buffer = renderer.GetTransientsBuffer();
@ -584,7 +594,8 @@ std::optional<Rect> StrokePathGeometry::GetCoverage(
if (determinant == 0) {
return std::nullopt;
}
Scalar min_size = 1.0f / sqrt(std::abs(determinant));
// Use the most conervative coverage setting.
Scalar min_size = kMinStrokeSize / sqrt(std::abs(determinant));
max_radius *= std::max(stroke_width_, min_size);
return path_bounds->Expand(max_radius).TransformBounds(transform);
}

View File

@ -460,6 +460,9 @@ impeller_Play_AiksTest_CanRenderTextWithLargePerspectiveTransform_Vulkan.png
impeller_Play_AiksTest_CanRenderThickCurvedStrokes_Metal.png
impeller_Play_AiksTest_CanRenderThickCurvedStrokes_OpenGLES.png
impeller_Play_AiksTest_CanRenderThickCurvedStrokes_Vulkan.png
impeller_Play_AiksTest_CanRenderThinCurvedStrokes_Metal.png
impeller_Play_AiksTest_CanRenderThinCurvedStrokes_OpenGLES.png
impeller_Play_AiksTest_CanRenderThinCurvedStrokes_Vulkan.png
impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_Metal.png
impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_OpenGLES.png
impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_Vulkan.png