Skip to content

Commit e35f850

Browse files
author
Jonah Williams
authored
[Impeller] specialize the geometry for drawRect (flutter#36914)
1 parent 30cec21 commit e35f850

File tree

6 files changed

+113
-3
lines changed

6 files changed

+113
-3
lines changed

impeller/aiks/canvas.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,15 @@ void Canvas::DrawRect(Rect rect, Paint paint) {
191191
if (AttemptDrawBlurredRRect(rect, 0, paint)) {
192192
return;
193193
}
194-
DrawPath(PathBuilder{}.AddRect(rect).TakePath(), std::move(paint));
194+
195+
Entity entity;
196+
entity.SetTransformation(GetCurrentTransformation());
197+
entity.SetStencilDepth(GetStencilDepth());
198+
entity.SetBlendMode(paint.blend_mode);
199+
entity.SetContents(paint.WithFilters(
200+
paint.CreateContentsForGeometry(Geometry::MakeRect(rect))));
201+
202+
GetCurrentPass().AddEntity(std::move(entity));
195203
}
196204

197205
void Canvas::DrawRRect(Rect rect, Scalar corner_radius, Paint paint) {

impeller/aiks/paint.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ std::shared_ptr<Contents> Paint::CreateContentsForEntity(Path path,
2323
stroke_join);
2424
break;
2525
}
26+
return CreateContentsForGeometry(std::move(geometry));
27+
}
2628

29+
std::shared_ptr<Contents> Paint::CreateContentsForGeometry(
30+
std::unique_ptr<Geometry> geometry) const {
2731
if (color_source.has_value()) {
2832
auto& source = color_source.value();
2933
auto contents = source();

impeller/aiks/paint.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ struct Paint {
9191
std::shared_ptr<Contents> CreateContentsForEntity(Path path = {},
9292
bool cover = false) const;
9393

94+
std::shared_ptr<Contents> CreateContentsForGeometry(
95+
std::unique_ptr<Geometry> geometry) const;
96+
9497
private:
9598
std::shared_ptr<Contents> WithMaskBlur(std::shared_ptr<Contents> input,
9699
bool is_solid_color,

impeller/entity/entity_unittests.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,14 @@ TEST_P(EntityTest, FilterCoverageRespectsCropRect) {
180180
}
181181

182182
TEST_P(EntityTest, CanDrawRect) {
183+
auto contents = std::make_shared<SolidColorContents>();
184+
contents->SetGeometry(Geometry::MakeRect({100, 100, 100, 100}));
185+
contents->SetColor(Color::Red());
186+
183187
Entity entity;
184188
entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
185-
entity.SetContents(SolidColorContents::Make(
186-
PathBuilder{}.AddRect({100, 100, 100, 100}).TakePath(), Color::Red()));
189+
entity.SetContents(contents);
190+
187191
ASSERT_TRUE(OpenPlaygroundHere(entity));
188192
}
189193

impeller/entity/geometry.cc

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ std::unique_ptr<Geometry> Geometry::MakeCover() {
4242
return std::make_unique<CoverGeometry>();
4343
}
4444

45+
std::unique_ptr<Geometry> Geometry::MakeRect(Rect rect) {
46+
return std::make_unique<RectGeometry>(rect);
47+
}
48+
4549
/////// Vertices Geometry ///////
4650

4751
VerticesGeometry::VerticesGeometry(Vertices vertices)
@@ -695,4 +699,54 @@ std::optional<Rect> CoverGeometry::GetCoverage(const Matrix& transform) const {
695699
return Rect::MakeMaximum();
696700
}
697701

702+
/////// Rect Geometry ///////
703+
704+
RectGeometry::RectGeometry(Rect rect) : rect_(rect) {}
705+
706+
RectGeometry::~RectGeometry() = default;
707+
708+
GeometryResult RectGeometry::GetPositionBuffer(const ContentContext& renderer,
709+
const Entity& entity,
710+
RenderPass& pass) {
711+
constexpr uint16_t kRectIndicies[4] = {0, 1, 2, 3};
712+
auto& host_buffer = pass.GetTransientsBuffer();
713+
return GeometryResult{
714+
.type = PrimitiveType::kTriangleStrip,
715+
.vertex_buffer = {.vertex_buffer = host_buffer.Emplace(
716+
rect_.GetPoints().data(), 8 * sizeof(float),
717+
alignof(float)),
718+
.index_buffer = host_buffer.Emplace(
719+
kRectIndicies, 4 * sizeof(uint16_t),
720+
alignof(uint16_t)),
721+
.index_count = 4,
722+
.index_type = IndexType::k16bit},
723+
.prevent_overdraw = false,
724+
};
725+
}
726+
727+
GeometryResult RectGeometry::GetPositionColorBuffer(
728+
const ContentContext& renderer,
729+
const Entity& entity,
730+
RenderPass& pass,
731+
Color paint_color,
732+
BlendMode blend_mode) {
733+
// TODO(jonahwilliams): support per-color vertex in rect geometry.
734+
return {};
735+
}
736+
737+
GeometryResult RectGeometry::GetPositionUVBuffer(const ContentContext& renderer,
738+
const Entity& entity,
739+
RenderPass& pass) {
740+
// TODO(jonahwilliams): support texture coordinates in rect geometry.
741+
return {};
742+
}
743+
744+
GeometryVertexType RectGeometry::GetVertexType() const {
745+
return GeometryVertexType::kPosition;
746+
}
747+
748+
std::optional<Rect> RectGeometry::GetCoverage(const Matrix& transform) const {
749+
return rect_;
750+
}
751+
698752
} // namespace impeller

impeller/entity/geometry.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class Geometry {
6161

6262
static std::unique_ptr<Geometry> MakeCover();
6363

64+
static std::unique_ptr<Geometry> MakeRect(Rect rect);
65+
6466
virtual GeometryResult GetPositionBuffer(const ContentContext& renderer,
6567
const Entity& entity,
6668
RenderPass& pass) = 0;
@@ -272,4 +274,39 @@ class CoverGeometry : public Geometry {
272274
FML_DISALLOW_COPY_AND_ASSIGN(CoverGeometry);
273275
};
274276

277+
class RectGeometry : public Geometry {
278+
public:
279+
explicit RectGeometry(Rect rect);
280+
281+
~RectGeometry();
282+
283+
private:
284+
// |Geometry|
285+
GeometryResult GetPositionBuffer(const ContentContext& renderer,
286+
const Entity& entity,
287+
RenderPass& pass) override;
288+
289+
// |Geometry|
290+
GeometryResult GetPositionColorBuffer(const ContentContext& renderer,
291+
const Entity& entity,
292+
RenderPass& pass,
293+
Color paint_color,
294+
BlendMode blend_mode) override;
295+
296+
// |Geometry|
297+
GeometryResult GetPositionUVBuffer(const ContentContext& renderer,
298+
const Entity& entity,
299+
RenderPass& pass) override;
300+
301+
// |Geometry|
302+
GeometryVertexType GetVertexType() const override;
303+
304+
// |Geometry|
305+
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
306+
307+
Rect rect_;
308+
309+
FML_DISALLOW_COPY_AND_ASSIGN(RectGeometry);
310+
};
311+
275312
} // namespace impeller

0 commit comments

Comments
 (0)