[Impeller] Remove the use of a subpixel minimum stroke size for MSAA (flutter/engine#56223)

Based on https://github.com/flutter/engine/pull/55230

Fixes https://github.com/flutter/flutter/issues/156438
This commit is contained in:
Jason Simmons
2024-10-30 11:45:45 -07:00
committed by GitHub
parent bbe385cf21
commit d24eb30b3d
6 changed files with 17 additions and 38 deletions

View File

@@ -42,11 +42,9 @@ GeometryResult CircleGeometry::GetPositionBuffer(const ContentContext& renderer,
RenderPass& pass) const {
auto& transform = entity.GetTransform();
Scalar half_width = stroke_width_ < 0
? 0.0
: LineGeometry::ComputePixelHalfWidth(
transform, stroke_width_,
pass.GetSampleCount() == SampleCount::kCount4);
Scalar half_width = stroke_width_ < 0 ? 0.0
: LineGeometry::ComputePixelHalfWidth(
transform, stroke_width_);
const std::shared_ptr<Tessellator>& tessellator = renderer.GetTessellator();

View File

@@ -133,9 +133,7 @@ bool Geometry::CanApplyMaskFilter() const {
Scalar Geometry::ComputeStrokeAlphaCoverage(const Matrix& transform,
Scalar stroke_width) {
Scalar scaled_stroke_width = transform.GetMaxBasisLengthXY() * stroke_width;
// If the stroke width is 0 or greater than kMinStrokeSizeMSAA, don't apply
// any additional alpha. This is intended to match Skia behavior.
if (scaled_stroke_width == 0.0 || scaled_stroke_width >= kMinStrokeSizeMSAA) {
if (scaled_stroke_width == 0.0 || scaled_stroke_width >= kMinStrokeSize) {
return 1.0;
}
// This scalling is eyeballed from Skia.

View File

@@ -16,11 +16,6 @@ namespace impeller {
class Tessellator;
/// @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;
struct GeometryResult {

View File

@@ -15,21 +15,19 @@ LineGeometry::LineGeometry(Point p0, Point p1, Scalar width, Cap cap)
LineGeometry::~LineGeometry() = default;
Scalar LineGeometry::ComputePixelHalfWidth(const Matrix& transform,
Scalar width,
bool msaa) {
Scalar width) {
Scalar max_basis = transform.GetMaxBasisLengthXY();
if (max_basis == 0) {
return {};
}
Scalar min_size = (msaa ? kMinStrokeSize : kMinStrokeSizeMSAA) / max_basis;
Scalar min_size = kMinStrokeSize / max_basis;
return std::max(width, min_size) * 0.5f;
}
Vector2 LineGeometry::ComputeAlongVector(const Matrix& transform,
bool allow_zero_length,
bool msaa) const {
Scalar stroke_half_width = ComputePixelHalfWidth(transform, width_, msaa);
bool allow_zero_length) const {
Scalar stroke_half_width = ComputePixelHalfWidth(transform, width_);
if (stroke_half_width < kEhCloseEnough) {
return {};
}
@@ -49,9 +47,8 @@ Vector2 LineGeometry::ComputeAlongVector(const Matrix& transform,
bool LineGeometry::ComputeCorners(Point corners[4],
const Matrix& transform,
bool extend_endpoints,
bool msaa) const {
auto along = ComputeAlongVector(transform, extend_endpoints, msaa);
bool extend_endpoints) const {
auto along = ComputeAlongVector(transform, extend_endpoints);
if (along.IsZero()) {
return false;
}
@@ -80,8 +77,7 @@ GeometryResult LineGeometry::GetPositionBuffer(const ContentContext& renderer,
using VT = SolidFillVertexShader::PerVertexData;
auto& transform = entity.GetTransform();
auto radius = ComputePixelHalfWidth(
transform, width_, pass.GetSampleCount() == SampleCount::kCount4);
auto radius = ComputePixelHalfWidth(transform, width_);
if (cap_ == Cap::kRound) {
std::shared_ptr<Tessellator> tessellator = renderer.GetTessellator();
@@ -90,8 +86,7 @@ GeometryResult LineGeometry::GetPositionBuffer(const ContentContext& renderer,
}
Point corners[4];
if (!ComputeCorners(corners, transform, cap_ == Cap::kSquare,
pass.GetSampleCount() == SampleCount::kCount4)) {
if (!ComputeCorners(corners, transform, cap_ == Cap::kSquare)) {
return kEmptyResult;
}
@@ -123,7 +118,7 @@ GeometryResult LineGeometry::GetPositionBuffer(const ContentContext& renderer,
std::optional<Rect> LineGeometry::GetCoverage(const Matrix& transform) const {
Point corners[4];
// Note: MSAA boolean doesn't matter for coverage computation.
if (!ComputeCorners(corners, transform, cap_ != Cap::kButt, /*msaa=*/false)) {
if (!ComputeCorners(corners, transform, cap_ != Cap::kButt)) {
return {};
}

View File

@@ -15,9 +15,7 @@ class LineGeometry final : public Geometry {
~LineGeometry() override;
static Scalar ComputePixelHalfWidth(const Matrix& transform,
Scalar width,
bool msaa);
static Scalar ComputePixelHalfWidth(const Matrix& transform, Scalar width);
// |Geometry|
bool CoversArea(const Matrix& transform, const Rect& rect) const override;
@@ -44,12 +42,10 @@ class LineGeometry final : public Geometry {
// @return true if the transform and width were not degenerate
bool ComputeCorners(Point corners[4],
const Matrix& transform,
bool extend_endpoints,
bool msaa) const;
bool extend_endpoints) const;
Vector2 ComputeAlongVector(const Matrix& transform,
bool allow_zero_length,
bool msaa) const;
bool allow_zero_length) const;
// |Geometry|
GeometryResult GetPositionBuffer(const ContentContext& renderer,

View File

@@ -574,10 +574,7 @@ GeometryResult StrokePathGeometry::GetPositionBuffer(
return {};
}
Scalar min_size =
(pass.GetSampleCount() == SampleCount::kCount4 ? kMinStrokeSizeMSAA
: kMinStrokeSize) /
max_basis;
Scalar min_size = kMinStrokeSize / max_basis;
Scalar stroke_width = std::max(stroke_width_, min_size);
auto& host_buffer = renderer.GetTransientsBuffer();