[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:
@@ -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();
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {};
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user