diff --git a/engine/src/flutter/impeller/entity/geometry/geometry_unittests.cc b/engine/src/flutter/impeller/entity/geometry/geometry_unittests.cc index 56354c1ad48..c56c16613bd 100644 --- a/engine/src/flutter/impeller/entity/geometry/geometry_unittests.cc +++ b/engine/src/flutter/impeller/entity/geometry/geometry_unittests.cc @@ -165,6 +165,26 @@ TEST(EntityGeometryTest, StrokePathGeometryTransformOfLine) { EXPECT_SOLID_VERTICES_NEAR(vertices, expected); + { + auto uv_vertices = + ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVerticesUV( + polyline, 10.0f, 10.0f, Join::kBevel, Cap::kButt, 1.0, // + Point(50.0f, 40.0f), Size(20.0f, 40.0f), Matrix()); + // uvx = (x - 50) / 20 + // uvy = (y - 40) / 40 + auto uv = [](const Point& p) { + return Point((p.x - 50.0f) / 20.0f, // + (p.y - 40.0f) / 40.0f); + }; + std::vector uv_expected; + for (size_t i = 0; i < expected.size(); i++) { + auto p = expected[i].position; + uv_expected.push_back({.position = p, .texture_coords = uv(p)}); + } + + EXPECT_TEXTURE_VERTICES_NEAR(uv_vertices, uv_expected); + } + { auto uv_vertices = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVerticesUV( diff --git a/engine/src/flutter/impeller/entity/geometry/stroke_path_geometry.cc b/engine/src/flutter/impeller/entity/geometry/stroke_path_geometry.cc index ba3d2fe8cd5..2f0f988e403 100644 --- a/engine/src/flutter/impeller/entity/geometry/stroke_path_geometry.cc +++ b/engine/src/flutter/impeller/entity/geometry/stroke_path_geometry.cc @@ -47,27 +47,45 @@ class PositionWriter { class PositionUVWriter { public: - PositionUVWriter(Point texture_origin, - Size texture_coverage, + PositionUVWriter(const Point& texture_origin, + const Size& texture_size, const Matrix& effect_transform) - : uv_transform_(Matrix::MakeScale(1 / texture_coverage) * - Matrix::MakeTranslation(-texture_origin) * - effect_transform) {} + : texture_origin_(texture_origin), + texture_size_(texture_size), + effect_transform_(effect_transform) {} - const std::vector& GetData() const { + const std::vector& GetData() { + if (effect_transform_.IsIdentity()) { + auto origin = texture_origin_; + auto scale = 1.0 / texture_size_; + + for (auto& pvd : data_) { + pvd.texture_coords = (pvd.position - origin) * scale; + } + } else { + auto texture_rect = Rect::MakeOriginSize(texture_origin_, texture_size_); + Matrix uv_transform = + texture_rect.GetNormalizingTransform() * effect_transform_; + + for (auto& pvd : data_) { + pvd.texture_coords = uv_transform * pvd.position; + } + } return data_; } void AppendVertex(const Point& point) { data_.emplace_back(TextureFillVertexShader::PerVertexData{ .position = point, - .texture_coords = uv_transform_ * point, + // .texture_coords = default, will be filled in during |GetData()| }); } private: std::vector data_ = {}; - const Matrix uv_transform_; + const Point texture_origin_; + const Size texture_size_; + const Matrix effect_transform_; }; template