@@ -20,7 +20,7 @@ namespace impeller {
20
20
std::pair<std::vector<Point>, std::vector<uint16_t >> TessellateConvex (
21
21
Path::Polyline polyline) {
22
22
std::vector<Point> output;
23
- std::vector<uint16_t > index ;
23
+ std::vector<uint16_t > indices ;
24
24
25
25
for (auto j = 0u ; j < polyline.contours .size (); j++) {
26
26
auto [start, end] = polyline.GetContourPointBounds (j);
@@ -39,12 +39,12 @@ std::pair<std::vector<Point>, std::vector<uint16_t>> TessellateConvex(
39
39
const auto & point_b = polyline.points [i];
40
40
output.emplace_back (point_b);
41
41
42
- index .emplace_back (0 );
43
- index .emplace_back (i - 1 );
44
- index .emplace_back (i);
42
+ indices .emplace_back (0 );
43
+ indices .emplace_back (i - 1 );
44
+ indices .emplace_back (i);
45
45
}
46
46
}
47
- return std::make_pair (output, index );
47
+ return std::make_pair (output, indices );
48
48
}
49
49
50
50
Geometry::Geometry () = default ;
@@ -64,11 +64,6 @@ std::unique_ptr<Geometry> Geometry::MakeFillPath(const Path& path) {
64
64
return std::make_unique<FillPathGeometry>(path);
65
65
}
66
66
67
- // static
68
- std::unique_ptr<Geometry> Geometry::MakeRRect (Rect rect, Scalar corner_radius) {
69
- return std::make_unique<RRectGeometry>(rect, corner_radius);
70
- }
71
-
72
67
std::unique_ptr<Geometry> Geometry::MakeStrokePath (const Path& path,
73
68
Scalar stroke_width,
74
69
Scalar miter_limit,
@@ -139,14 +134,14 @@ GeometryResult FillPathGeometry::GetPositionBuffer(
139
134
140
135
if (path_.GetFillType () == FillType::kNonZero && //
141
136
path_.IsConvex ()) {
142
- auto [points, indicies ] = TessellateConvex (
137
+ auto [points, indices ] = TessellateConvex (
143
138
path_.CreatePolyline (entity.GetTransformation ().GetMaxBasisLength ()));
144
139
145
140
vertex_buffer.vertex_buffer = host_buffer.Emplace (
146
141
points.data (), points.size () * sizeof (Point), alignof (Point));
147
142
vertex_buffer.index_buffer = host_buffer.Emplace (
148
- indicies .data (), indicies .size () * sizeof (uint16_t ), alignof (uint16_t ));
149
- vertex_buffer.index_count = indicies .size ();
143
+ indices .data (), indices .size () * sizeof (uint16_t ), alignof (uint16_t ));
144
+ vertex_buffer.index_count = indices .size ();
150
145
vertex_buffer.index_type = IndexType::k16bit;
151
146
152
147
return GeometryResult{
@@ -193,6 +188,37 @@ GeometryResult FillPathGeometry::GetPositionUVBuffer(
193
188
RenderPass& pass) {
194
189
using VS = TextureFillVertexShader;
195
190
191
+ if (path_.GetFillType () == FillType::kNonZero && //
192
+ path_.IsConvex ()) {
193
+ auto [points, indices] = TessellateConvex (
194
+ path_.CreatePolyline (entity.GetTransformation ().GetMaxBasisLength ()));
195
+
196
+ VertexBufferBuilder<VS::PerVertexData> vertex_builder;
197
+ vertex_builder.Reserve (points.size ());
198
+ vertex_builder.ReserveIndices (indices.size ());
199
+ for (auto i = 0u ; i < points.size (); i++) {
200
+ VS::PerVertexData data;
201
+ data.position = points[i];
202
+ auto coverage_coords =
203
+ ((points[i] - texture_coverage.origin ) / texture_coverage.size ) /
204
+ texture_coverage.size ;
205
+ data.texture_coords = effect_transform * coverage_coords;
206
+ vertex_builder.AppendVertex (data);
207
+ }
208
+ for (auto i = 0u ; i < indices.size (); i++) {
209
+ vertex_builder.AppendIndex (indices[i]);
210
+ }
211
+
212
+ return GeometryResult{
213
+ .type = PrimitiveType::kTriangle ,
214
+ .vertex_buffer =
215
+ vertex_builder.CreateVertexBuffer (pass.GetTransientsBuffer ()),
216
+ .transform = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
217
+ entity.GetTransformation (),
218
+ .prevent_overdraw = false ,
219
+ };
220
+ }
221
+
196
222
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
197
223
auto tesselation_result = renderer.GetTessellator ()->Tessellate (
198
224
path_.GetFillType (),
@@ -777,163 +803,4 @@ std::optional<Rect> RectGeometry::GetCoverage(const Matrix& transform) const {
777
803
return rect_.TransformBounds (transform);
778
804
}
779
805
780
- // ///// RRect Geometry ///////
781
-
782
- RRectGeometry::RRectGeometry (Rect rect, Scalar corner_radius)
783
- : rect_(rect), corner_radius_(corner_radius) {}
784
-
785
- RRectGeometry::~RRectGeometry () = default ;
786
-
787
- static void AppendRRectCorner (Path::Polyline polyline,
788
- Point corner,
789
- VertexBufferBuilder<Point>& vtx_builder) {
790
- for (auto i = 1u ; i < polyline.points .size (); i++) {
791
- vtx_builder.AddVertices ({
792
- polyline.points [i - 1 ],
793
- polyline.points [i],
794
- corner,
795
- });
796
- }
797
- }
798
-
799
- VertexBufferBuilder<Point> RRectGeometry::CreatePositionBuffer (
800
- const Entity& entity) const {
801
- VertexBufferBuilder<Point> vtx_builder;
802
-
803
- // The rounded rectangle is split into parts:
804
- // * four corner sections defined by an arc
805
- // * An interior shape composed of three rectangles.
806
-
807
- auto left = rect_.GetLeft ();
808
- auto right = rect_.GetRight ();
809
- auto bottom = rect_.GetBottom ();
810
- auto top = rect_.GetTop ();
811
- auto radii = PathBuilder::RoundingRadii (corner_radius_, corner_radius_,
812
- corner_radius_, corner_radius_);
813
-
814
- auto topLeft =
815
- PathBuilder{}
816
- .MoveTo ({rect_.origin .x , rect_.origin .y + corner_radius_})
817
- .AddRoundedRectTopLeft (rect_, radii)
818
- .TakePath ()
819
- .CreatePolyline (entity.GetTransformation ().GetMaxBasisLength ());
820
- auto topRight =
821
- PathBuilder{}
822
- .MoveTo ({right - radii.top_right .x , rect_.origin .y })
823
- .AddRoundedRectTopRight (rect_, radii)
824
- .TakePath ()
825
- .CreatePolyline (entity.GetTransformation ().GetMaxBasisLength ());
826
- auto bottomLeft =
827
- PathBuilder{}
828
- .MoveTo ({left + corner_radius_, bottom})
829
- .AddRoundedRectBottomLeft (rect_, radii)
830
- .TakePath ()
831
- .CreatePolyline (entity.GetTransformation ().GetMaxBasisLength ());
832
- auto bottomRight =
833
- PathBuilder{}
834
- .MoveTo ({right, bottom - corner_radius_})
835
- .AddRoundedRectBottomRight (rect_, radii)
836
- .TakePath ()
837
- .CreatePolyline (entity.GetTransformation ().GetMaxBasisLength ());
838
-
839
- vtx_builder.Reserve (12 * (topLeft.points .size () - 1 ) + 18 );
840
-
841
- AppendRRectCorner (topLeft, Point (left + corner_radius_, top + corner_radius_),
842
- vtx_builder);
843
-
844
- AppendRRectCorner (topRight,
845
- Point (right - corner_radius_, top + corner_radius_),
846
- vtx_builder);
847
-
848
- AppendRRectCorner (bottomLeft,
849
- Point (left + corner_radius_, bottom - corner_radius_),
850
- vtx_builder);
851
-
852
- AppendRRectCorner (bottomRight,
853
- Point (right - corner_radius_, bottom - corner_radius_),
854
- vtx_builder);
855
- vtx_builder.AddVertices ({
856
- // Top Component.
857
- Point (left + corner_radius_, top + corner_radius_),
858
- Point (left + corner_radius_, top),
859
- Point (right - corner_radius_, top + corner_radius_),
860
-
861
- Point (left + corner_radius_, top),
862
- Point (right - corner_radius_, top + corner_radius_),
863
- Point (right - corner_radius_, top),
864
-
865
- // Bottom Component.
866
- Point (left + corner_radius_, bottom - corner_radius_),
867
- Point (left + corner_radius_, bottom),
868
- Point (right - corner_radius_, bottom - corner_radius_),
869
-
870
- Point (left + corner_radius_, bottom),
871
- Point (right - corner_radius_, bottom - corner_radius_),
872
- Point (right - corner_radius_, bottom),
873
-
874
- // // Center Component.
875
- Point (left, top + corner_radius_),
876
- Point (right, top + corner_radius_),
877
- Point (right, bottom - corner_radius_),
878
-
879
- Point (left, top + corner_radius_),
880
- Point (left, bottom - corner_radius_),
881
- Point (right, bottom - corner_radius_),
882
- });
883
-
884
- return vtx_builder;
885
- }
886
-
887
- GeometryResult RRectGeometry::GetPositionBuffer (const ContentContext& renderer,
888
- const Entity& entity,
889
- RenderPass& pass) {
890
- auto vtx_builder = CreatePositionBuffer (entity);
891
-
892
- return GeometryResult{
893
- .type = PrimitiveType::kTriangle ,
894
- .vertex_buffer =
895
- vtx_builder.CreateVertexBuffer (pass.GetTransientsBuffer ()),
896
- .transform = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
897
- entity.GetTransformation (),
898
- .prevent_overdraw = false ,
899
- };
900
- }
901
-
902
- GeometryResult RRectGeometry::GetPositionUVBuffer (
903
- Rect texture_coverage,
904
- Matrix effect_transform,
905
- const ContentContext& renderer,
906
- const Entity& entity,
907
- RenderPass& pass) {
908
- auto vtx_builder = CreatePositionBuffer (entity);
909
-
910
- VertexBufferBuilder<TextureFillVertexShader::PerVertexData> vertex_builder;
911
- vtx_builder.IterateVertices (
912
- [&vertex_builder, &texture_coverage, &effect_transform](Point position) {
913
- TextureFillVertexShader::PerVertexData data;
914
- data.position = position;
915
- auto coverage_coords =
916
- (position - texture_coverage.origin ) / texture_coverage.size ;
917
- data.texture_coords = effect_transform * coverage_coords;
918
- vertex_builder.AppendVertex (data);
919
- });
920
-
921
- return GeometryResult{
922
- .type = PrimitiveType::kTriangle ,
923
- .vertex_buffer =
924
- vertex_builder.CreateVertexBuffer (pass.GetTransientsBuffer ()),
925
- .transform = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
926
- entity.GetTransformation (),
927
- .prevent_overdraw = true ,
928
- };
929
- }
930
-
931
- GeometryVertexType RRectGeometry::GetVertexType () const {
932
- return GeometryVertexType::kPosition ;
933
- }
934
-
935
- std::optional<Rect> RRectGeometry::GetCoverage (const Matrix& transform) const {
936
- return rect_.TransformBounds (transform);
937
- }
938
-
939
806
} // namespace impeller
0 commit comments