diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index c55edb70df72d..1b5e2f05e5f5a 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -191,7 +191,15 @@ void Canvas::DrawRect(Rect rect, Paint paint) { if (AttemptDrawBlurredRRect(rect, 0, paint)) { return; } - DrawPath(PathBuilder{}.AddRect(rect).TakePath(), std::move(paint)); + + Entity entity; + entity.SetTransformation(GetCurrentTransformation()); + entity.SetStencilDepth(GetStencilDepth()); + entity.SetBlendMode(paint.blend_mode); + entity.SetContents(paint.WithFilters( + paint.CreateContentsForGeometry(Geometry::MakeRect(rect)))); + + GetCurrentPass().AddEntity(std::move(entity)); } void Canvas::DrawRRect(Rect rect, Scalar corner_radius, Paint paint) { diff --git a/impeller/aiks/paint.cc b/impeller/aiks/paint.cc index e413266256403..6b134037a75ab 100644 --- a/impeller/aiks/paint.cc +++ b/impeller/aiks/paint.cc @@ -23,7 +23,11 @@ std::shared_ptr Paint::CreateContentsForEntity(Path path, stroke_join); break; } + return CreateContentsForGeometry(std::move(geometry)); +} +std::shared_ptr Paint::CreateContentsForGeometry( + std::unique_ptr geometry) const { if (color_source.has_value()) { auto& source = color_source.value(); auto contents = source(); diff --git a/impeller/aiks/paint.h b/impeller/aiks/paint.h index 7a9f0b55bf2ba..9f45539eee20f 100644 --- a/impeller/aiks/paint.h +++ b/impeller/aiks/paint.h @@ -91,6 +91,9 @@ struct Paint { std::shared_ptr CreateContentsForEntity(Path path = {}, bool cover = false) const; + std::shared_ptr CreateContentsForGeometry( + std::unique_ptr geometry) const; + private: std::shared_ptr WithMaskBlur(std::shared_ptr input, bool is_solid_color, diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 92578db0409a7..3568c2d0f627e 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -180,10 +180,14 @@ TEST_P(EntityTest, FilterCoverageRespectsCropRect) { } TEST_P(EntityTest, CanDrawRect) { + auto contents = std::make_shared(); + contents->SetGeometry(Geometry::MakeRect({100, 100, 100, 100})); + contents->SetColor(Color::Red()); + Entity entity; entity.SetTransformation(Matrix::MakeScale(GetContentScale())); - entity.SetContents(SolidColorContents::Make( - PathBuilder{}.AddRect({100, 100, 100, 100}).TakePath(), Color::Red())); + entity.SetContents(contents); + ASSERT_TRUE(OpenPlaygroundHere(entity)); } diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index aad8042d4c4f9..5389506f12e05 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -42,6 +42,10 @@ std::unique_ptr Geometry::MakeCover() { return std::make_unique(); } +std::unique_ptr Geometry::MakeRect(Rect rect) { + return std::make_unique(rect); +} + /////// Vertices Geometry /////// VerticesGeometry::VerticesGeometry(Vertices vertices) @@ -695,4 +699,54 @@ std::optional CoverGeometry::GetCoverage(const Matrix& transform) const { return Rect::MakeMaximum(); } +/////// Rect Geometry /////// + +RectGeometry::RectGeometry(Rect rect) : rect_(rect) {} + +RectGeometry::~RectGeometry() = default; + +GeometryResult RectGeometry::GetPositionBuffer(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) { + constexpr uint16_t kRectIndicies[4] = {0, 1, 2, 3}; + auto& host_buffer = pass.GetTransientsBuffer(); + return GeometryResult{ + .type = PrimitiveType::kTriangleStrip, + .vertex_buffer = {.vertex_buffer = host_buffer.Emplace( + rect_.GetPoints().data(), 8 * sizeof(float), + alignof(float)), + .index_buffer = host_buffer.Emplace( + kRectIndicies, 4 * sizeof(uint16_t), + alignof(uint16_t)), + .index_count = 4, + .index_type = IndexType::k16bit}, + .prevent_overdraw = false, + }; +} + +GeometryResult RectGeometry::GetPositionColorBuffer( + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass, + Color paint_color, + BlendMode blend_mode) { + // TODO(jonahwilliams): support per-color vertex in rect geometry. + return {}; +} + +GeometryResult RectGeometry::GetPositionUVBuffer(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) { + // TODO(jonahwilliams): support texture coordinates in rect geometry. + return {}; +} + +GeometryVertexType RectGeometry::GetVertexType() const { + return GeometryVertexType::kPosition; +} + +std::optional RectGeometry::GetCoverage(const Matrix& transform) const { + return rect_; +} + } // namespace impeller diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index e0b69042b9761..2ca2e61fc406d 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -61,6 +61,8 @@ class Geometry { static std::unique_ptr MakeCover(); + static std::unique_ptr MakeRect(Rect rect); + virtual GeometryResult GetPositionBuffer(const ContentContext& renderer, const Entity& entity, RenderPass& pass) = 0; @@ -272,4 +274,39 @@ class CoverGeometry : public Geometry { FML_DISALLOW_COPY_AND_ASSIGN(CoverGeometry); }; +class RectGeometry : public Geometry { + public: + explicit RectGeometry(Rect rect); + + ~RectGeometry(); + + private: + // |Geometry| + GeometryResult GetPositionBuffer(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) override; + + // |Geometry| + GeometryResult GetPositionColorBuffer(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass, + Color paint_color, + BlendMode blend_mode) override; + + // |Geometry| + GeometryResult GetPositionUVBuffer(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) override; + + // |Geometry| + GeometryVertexType GetVertexType() const override; + + // |Geometry| + std::optional GetCoverage(const Matrix& transform) const override; + + Rect rect_; + + FML_DISALLOW_COPY_AND_ASSIGN(RectGeometry); +}; + } // namespace impeller