[Impeller] specialize the geometry for drawRect (flutter/engine#36914)

This commit is contained in:
Jonah Williams 2022-10-21 17:22:57 -07:00 committed by GitHub
parent 0c8fd45248
commit 300d0827ad
6 changed files with 113 additions and 3 deletions

View File

@ -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) {

View File

@ -23,7 +23,11 @@ std::shared_ptr<Contents> Paint::CreateContentsForEntity(Path path,
stroke_join);
break;
}
return CreateContentsForGeometry(std::move(geometry));
}
std::shared_ptr<Contents> Paint::CreateContentsForGeometry(
std::unique_ptr<Geometry> geometry) const {
if (color_source.has_value()) {
auto& source = color_source.value();
auto contents = source();

View File

@ -91,6 +91,9 @@ struct Paint {
std::shared_ptr<Contents> CreateContentsForEntity(Path path = {},
bool cover = false) const;
std::shared_ptr<Contents> CreateContentsForGeometry(
std::unique_ptr<Geometry> geometry) const;
private:
std::shared_ptr<Contents> WithMaskBlur(std::shared_ptr<Contents> input,
bool is_solid_color,

View File

@ -180,10 +180,14 @@ TEST_P(EntityTest, FilterCoverageRespectsCropRect) {
}
TEST_P(EntityTest, CanDrawRect) {
auto contents = std::make_shared<SolidColorContents>();
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));
}

View File

@ -42,6 +42,10 @@ std::unique_ptr<Geometry> Geometry::MakeCover() {
return std::make_unique<CoverGeometry>();
}
std::unique_ptr<Geometry> Geometry::MakeRect(Rect rect) {
return std::make_unique<RectGeometry>(rect);
}
/////// Vertices Geometry ///////
VerticesGeometry::VerticesGeometry(Vertices vertices)
@ -695,4 +699,54 @@ std::optional<Rect> 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<Rect> RectGeometry::GetCoverage(const Matrix& transform) const {
return rect_;
}
} // namespace impeller

View File

@ -61,6 +61,8 @@ class Geometry {
static std::unique_ptr<Geometry> MakeCover();
static std::unique_ptr<Geometry> 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<Rect> GetCoverage(const Matrix& transform) const override;
Rect rect_;
FML_DISALLOW_COPY_AND_ASSIGN(RectGeometry);
};
} // namespace impeller