5
5
#include " impeller/entity/geometry.h"
6
6
#include " impeller/entity/contents/content_context.h"
7
7
#include " impeller/entity/position_color.vert.h"
8
+ #include " impeller/entity/texture_fill.vert.h"
8
9
#include " impeller/geometry/matrix.h"
9
10
#include " impeller/geometry/path_builder.h"
10
11
#include " impeller/renderer/device_buffer.h"
@@ -51,6 +52,40 @@ std::unique_ptr<Geometry> Geometry::MakeRect(Rect rect) {
51
52
return std::make_unique<RectGeometry>(rect);
52
53
}
53
54
55
+ static GeometryResult ComputeUVGeometryForRect (Rect source_rect,
56
+ Rect texture_coverage,
57
+ Matrix effect_transform,
58
+ const ContentContext& renderer,
59
+ const Entity& entity,
60
+ RenderPass& pass) {
61
+ constexpr uint16_t kRectIndicies [4 ] = {0 , 1 , 2 , 3 };
62
+ auto & host_buffer = pass.GetTransientsBuffer ();
63
+
64
+ std::vector<Point > data (8 );
65
+ auto points = source_rect.GetPoints ();
66
+ for (auto i = 0u , j = 0u ; i < 8 ; i += 2 , j++) {
67
+ data[i] = points[j];
68
+ data[i + 1 ] = effect_transform * ((points[j] - texture_coverage.origin ) /
69
+ texture_coverage.size );
70
+ }
71
+
72
+ return GeometryResult{
73
+ .type = PrimitiveType::kTriangleStrip ,
74
+ .vertex_buffer =
75
+ {
76
+ .vertex_buffer = host_buffer.Emplace (
77
+ data.data (), 16 * sizeof (float ), alignof (float )),
78
+ .index_buffer = host_buffer.Emplace (
79
+ kRectIndicies , 4 * sizeof (uint16_t ), alignof (uint16_t )),
80
+ .index_count = 4 ,
81
+ .index_type = IndexType::k16bit,
82
+ },
83
+ .transform = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
84
+ entity.GetTransformation (),
85
+ .prevent_overdraw = false ,
86
+ };
87
+ }
88
+
54
89
// ///// Path Geometry ///////
55
90
56
91
FillPathGeometry::FillPathGeometry (const Path& path) : path_(path) {}
@@ -89,6 +124,51 @@ GeometryResult FillPathGeometry::GetPositionBuffer(
89
124
};
90
125
}
91
126
127
+ // |Geometry|
128
+ GeometryResult FillPathGeometry::GetPositionUVBuffer (
129
+ Rect texture_coverage,
130
+ Matrix effect_transform,
131
+ const ContentContext& renderer,
132
+ const Entity& entity,
133
+ RenderPass& pass) {
134
+ using VS = TextureFillVertexShader;
135
+
136
+ VertexBufferBuilder<VS::PerVertexData> vertex_builder;
137
+ auto tesselation_result = renderer.GetTessellator ()->Tessellate (
138
+ path_.GetFillType (),
139
+ path_.CreatePolyline (entity.GetTransformation ().GetMaxBasisLength ()),
140
+ [&vertex_builder, &texture_coverage, &effect_transform](
141
+ const float * vertices, size_t vertices_count, const uint16_t * indices,
142
+ size_t indices_count) {
143
+ for (auto i = 0u ; i < vertices_count; i += 2 ) {
144
+ VS::PerVertexData data;
145
+ Point vtx = {vertices[i], vertices[i + 1 ]};
146
+ data.position = vtx;
147
+ auto coverage_coords =
148
+ ((vtx - texture_coverage.origin ) / texture_coverage.size ) /
149
+ texture_coverage.size ;
150
+ data.texture_coords = effect_transform * coverage_coords;
151
+ vertex_builder.AppendVertex (data);
152
+ }
153
+ FML_DCHECK (vertex_builder.GetVertexCount () == vertices_count / 2 );
154
+ for (auto i = 0u ; i < indices_count; i++) {
155
+ vertex_builder.AppendIndex (indices[i]);
156
+ }
157
+ return true ;
158
+ });
159
+ if (tesselation_result != Tessellator::Result::kSuccess ) {
160
+ return {};
161
+ }
162
+ return GeometryResult{
163
+ .type = PrimitiveType::kTriangle ,
164
+ .vertex_buffer =
165
+ vertex_builder.CreateVertexBuffer (pass.GetTransientsBuffer ()),
166
+ .transform = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
167
+ entity.GetTransformation (),
168
+ .prevent_overdraw = false ,
169
+ };
170
+ }
171
+
92
172
GeometryVertexType FillPathGeometry::GetVertexType () const {
93
173
return GeometryVertexType::kPosition ;
94
174
}
@@ -300,9 +380,9 @@ StrokePathGeometry::CapProc StrokePathGeometry::GetCapProc(Cap stroke_cap) {
300
380
}
301
381
302
382
// static
303
- VertexBuffer StrokePathGeometry::CreateSolidStrokeVertices (
383
+ VertexBufferBuilder<SolidFillVertexShader::PerVertexData>
384
+ StrokePathGeometry::CreateSolidStrokeVertices (
304
385
const Path& path,
305
- HostBuffer& buffer,
306
386
Scalar stroke_width,
307
387
Scalar scaled_miter_limit,
308
388
Cap cap,
@@ -422,7 +502,7 @@ VertexBuffer StrokePathGeometry::CreateSolidStrokeVertices(
422
502
}
423
503
}
424
504
425
- return vtx_builder. CreateVertexBuffer (buffer) ;
505
+ return vtx_builder;
426
506
}
427
507
428
508
GeometryResult StrokePathGeometry::GetPositionBuffer (
@@ -441,14 +521,59 @@ GeometryResult StrokePathGeometry::GetPositionBuffer(
441
521
Scalar stroke_width = std::max (stroke_width_, min_size);
442
522
443
523
auto & host_buffer = pass.GetTransientsBuffer ();
444
- auto vertex_buffer = CreateSolidStrokeVertices (
445
- path_, host_buffer, stroke_width, miter_limit_ * stroke_width_ * 0.5 ,
446
- stroke_cap_, GetJoinProc (stroke_join_), GetCapProc (stroke_cap_),
524
+ auto vertex_builder = CreateSolidStrokeVertices (
525
+ path_, stroke_width, miter_limit_ * stroke_width_ * 0.5 , stroke_cap_ ,
526
+ GetJoinProc (stroke_join_), GetCapProc (stroke_cap_),
447
527
entity.GetTransformation ().GetMaxBasisLength ());
448
528
449
529
return GeometryResult{
450
530
.type = PrimitiveType::kTriangleStrip ,
451
- .vertex_buffer = vertex_buffer,
531
+ .vertex_buffer = vertex_builder.CreateVertexBuffer (host_buffer),
532
+ .transform = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
533
+ entity.GetTransformation (),
534
+ .prevent_overdraw = true ,
535
+ };
536
+ }
537
+
538
+ GeometryResult StrokePathGeometry::GetPositionUVBuffer (
539
+ Rect texture_coverage,
540
+ Matrix effect_transform,
541
+ const ContentContext& renderer,
542
+ const Entity& entity,
543
+ RenderPass& pass) {
544
+ if (stroke_width_ < 0.0 ) {
545
+ return {};
546
+ }
547
+ auto determinant = entity.GetTransformation ().GetDeterminant ();
548
+ if (determinant == 0 ) {
549
+ return {};
550
+ }
551
+
552
+ Scalar min_size = 1 .0f / sqrt (std::abs (determinant));
553
+ Scalar stroke_width = std::max (stroke_width_, min_size);
554
+
555
+ auto & host_buffer = pass.GetTransientsBuffer ();
556
+ auto stroke_builder = CreateSolidStrokeVertices (
557
+ path_, stroke_width, miter_limit_ * stroke_width_ * 0.5 , stroke_cap_,
558
+ GetJoinProc (stroke_join_), GetCapProc (stroke_cap_),
559
+ entity.GetTransformation ().GetMaxBasisLength ());
560
+
561
+ VertexBufferBuilder<TextureFillVertexShader::PerVertexData> vertex_builder;
562
+ stroke_builder.IterateVertices (
563
+ [&vertex_builder, &texture_coverage,
564
+ &effect_transform](SolidFillVertexShader::PerVertexData old_vtx) {
565
+ TextureFillVertexShader::PerVertexData data;
566
+ data.position = old_vtx.position ;
567
+ auto coverage_coords = ((old_vtx.position - texture_coverage.origin ) /
568
+ texture_coverage.size ) /
569
+ texture_coverage.size ;
570
+ data.texture_coords = effect_transform * coverage_coords;
571
+ vertex_builder.AppendVertex (data);
572
+ });
573
+
574
+ return GeometryResult{
575
+ .type = PrimitiveType::kTriangleStrip ,
576
+ .vertex_buffer = vertex_builder.CreateVertexBuffer (host_buffer),
452
577
.transform = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
453
578
entity.GetTransformation (),
454
579
.prevent_overdraw = true ,
@@ -515,6 +640,18 @@ GeometryResult CoverGeometry::GetPositionBuffer(const ContentContext& renderer,
515
640
};
516
641
}
517
642
643
+ // |Geometry|
644
+ GeometryResult CoverGeometry::GetPositionUVBuffer (
645
+ Rect texture_coverage,
646
+ Matrix effect_transform,
647
+ const ContentContext& renderer,
648
+ const Entity& entity,
649
+ RenderPass& pass) {
650
+ auto rect = Rect (Size (pass.GetRenderTargetSize ()));
651
+ return ComputeUVGeometryForRect (rect, texture_coverage, effect_transform,
652
+ renderer, entity, pass);
653
+ }
654
+
518
655
GeometryVertexType CoverGeometry::GetVertexType () const {
519
656
return GeometryVertexType::kPosition ;
520
657
}
@@ -551,6 +688,16 @@ GeometryResult RectGeometry::GetPositionBuffer(const ContentContext& renderer,
551
688
};
552
689
}
553
690
691
+ // |Geometry|
692
+ GeometryResult RectGeometry::GetPositionUVBuffer (Rect texture_coverage,
693
+ Matrix effect_transform,
694
+ const ContentContext& renderer,
695
+ const Entity& entity,
696
+ RenderPass& pass) {
697
+ return ComputeUVGeometryForRect (rect_, texture_coverage, effect_transform,
698
+ renderer, entity, pass);
699
+ }
700
+
554
701
GeometryVertexType RectGeometry::GetVertexType () const {
555
702
return GeometryVertexType::kPosition ;
556
703
}
0 commit comments