diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 433a0c5085..e2b2d27243 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -1210,8 +1210,6 @@ FILE: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.cc FILE: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.h FILE: ../../../flutter/impeller/entity/contents/solid_color_contents.cc FILE: ../../../flutter/impeller/entity/contents/solid_color_contents.h -FILE: ../../../flutter/impeller/entity/contents/solid_fill_utils.cc -FILE: ../../../flutter/impeller/entity/contents/solid_fill_utils.h FILE: ../../../flutter/impeller/entity/contents/solid_stroke_contents.cc FILE: ../../../flutter/impeller/entity/contents/solid_stroke_contents.h FILE: ../../../flutter/impeller/entity/contents/sweep_gradient_contents.cc diff --git a/engine/src/flutter/impeller/aiks/canvas.cc b/engine/src/flutter/impeller/aiks/canvas.cc index 2c42a172cb..50ecd4b1be 100644 --- a/engine/src/flutter/impeller/aiks/canvas.cc +++ b/engine/src/flutter/impeller/aiks/canvas.cc @@ -209,7 +209,7 @@ void Canvas::DrawCircle(Point center, Scalar radius, Paint paint) { void Canvas::ClipPath(Path path, Entity::ClipOperation clip_op) { auto contents = std::make_shared(); - contents->SetPath(std::move(path)); + contents->SetGeometry(Geometry::MakePath(std::move(path))); contents->SetClipOperation(clip_op); Entity entity; diff --git a/engine/src/flutter/impeller/aiks/paint.cc b/engine/src/flutter/impeller/aiks/paint.cc index 238ec21025..c38d2c2bed 100644 --- a/engine/src/flutter/impeller/aiks/paint.cc +++ b/engine/src/flutter/impeller/aiks/paint.cc @@ -5,6 +5,7 @@ #include "impeller/aiks/paint.h" #include "impeller/entity/contents/solid_color_contents.h" #include "impeller/entity/contents/solid_stroke_contents.h" +#include "impeller/entity/geometry.h" namespace impeller { @@ -13,18 +14,18 @@ std::shared_ptr Paint::CreateContentsForEntity(Path path, if (color_source.has_value()) { auto& source = color_source.value(); auto contents = source(); - contents->SetPath(std::move(path)); + contents->SetGeometry(cover ? Geometry::MakeCover() + : Geometry::MakePath(std::move(path))); contents->SetAlpha(color.alpha); - contents->SetCover(cover); return contents; } switch (style) { case Style::kFill: { auto solid_color = std::make_shared(); - solid_color->SetPath(std::move(path)); + solid_color->SetGeometry(cover ? Geometry::MakeCover() + : Geometry::MakePath(std::move(path))); solid_color->SetColor(color); - solid_color->SetCover(cover); return solid_color; } case Style::kStroke: { diff --git a/engine/src/flutter/impeller/entity/BUILD.gn b/engine/src/flutter/impeller/entity/BUILD.gn index 3003b96859..e2c9f4944d 100644 --- a/engine/src/flutter/impeller/entity/BUILD.gn +++ b/engine/src/flutter/impeller/entity/BUILD.gn @@ -115,8 +115,6 @@ impeller_component("entity") { "contents/rrect_shadow_contents.h", "contents/solid_color_contents.cc", "contents/solid_color_contents.h", - "contents/solid_fill_utils.cc", - "contents/solid_fill_utils.h", "contents/solid_stroke_contents.cc", "contents/solid_stroke_contents.h", "contents/sweep_gradient_contents.cc", diff --git a/engine/src/flutter/impeller/entity/contents/clip_contents.cc b/engine/src/flutter/impeller/entity/contents/clip_contents.cc index bbe6c61aeb..2497e4daa9 100644 --- a/engine/src/flutter/impeller/entity/contents/clip_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/clip_contents.cc @@ -7,9 +7,7 @@ #include "fml/logging.h" #include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" -#include "impeller/entity/contents/solid_fill_utils.h" #include "impeller/entity/entity.h" -#include "impeller/geometry/path_builder.h" #include "impeller/renderer/formats.h" #include "impeller/renderer/render_pass.h" #include "impeller/renderer/vertex_buffer_builder.h" @@ -24,8 +22,8 @@ ClipContents::ClipContents() = default; ClipContents::~ClipContents() = default; -void ClipContents::SetPath(Path path) { - path_ = std::move(path); +void ClipContents::SetGeometry(std::unique_ptr geometry) { + geometry_ = std::move(geometry); } void ClipContents::SetClipOperation(Entity::ClipOperation clip_op) { @@ -52,8 +50,7 @@ Contents::StencilCoverage ClipContents::GetStencilCoverage( return { .type = StencilCoverage::Type::kAppend, .coverage = current_stencil_coverage->Intersection( - path_.GetTransformedBoundingBox(entity.GetTransformation()) - .value()), + geometry_->GetCoverage(entity.GetTransformation()).value()), }; } FML_UNREACHABLE(); @@ -119,9 +116,14 @@ bool ClipContents::Render(const ContentContext& renderer, } cmd.pipeline = renderer.GetClipPipeline(options); - cmd.BindVertices(CreateSolidFillVertices(renderer.GetTessellator(), path_, - pass.GetTransientsBuffer())); + auto& host_buffer = pass.GetTransientsBuffer(); + auto allocator = renderer.GetContext()->GetResourceAllocator(); + auto geometry_result = geometry_->GetPositionBuffer( + allocator, host_buffer, renderer.GetTessellator(), + pass.GetRenderTargetSize()); + cmd.BindVertices(geometry_result.vertex_buffer); + cmd.primitive_type = geometry_result.type; info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(); VS::BindVertInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(info)); diff --git a/engine/src/flutter/impeller/entity/contents/clip_contents.h b/engine/src/flutter/impeller/entity/contents/clip_contents.h index 9521aa05b9..b70c8ba863 100644 --- a/engine/src/flutter/impeller/entity/contents/clip_contents.h +++ b/engine/src/flutter/impeller/entity/contents/clip_contents.h @@ -11,6 +11,7 @@ #include "flutter/fml/macros.h" #include "impeller/entity/contents/contents.h" #include "impeller/entity/entity.h" +#include "impeller/entity/geometry.h" namespace impeller { @@ -20,7 +21,7 @@ class ClipContents final : public Contents { ~ClipContents(); - void SetPath(Path path); + void SetGeometry(std::unique_ptr geometry); void SetClipOperation(Entity::ClipOperation clip_op); @@ -42,7 +43,7 @@ class ClipContents final : public Contents { RenderPass& pass) const override; private: - Path path_; + std::unique_ptr geometry_; Entity::ClipOperation clip_op_ = Entity::ClipOperation::kIntersect; FML_DISALLOW_COPY_AND_ASSIGN(ClipContents); diff --git a/engine/src/flutter/impeller/entity/contents/color_source_contents.cc b/engine/src/flutter/impeller/entity/contents/color_source_contents.cc index 359a0e1dc5..37e079d878 100644 --- a/engine/src/flutter/impeller/entity/contents/color_source_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/color_source_contents.cc @@ -13,12 +13,12 @@ ColorSourceContents::ColorSourceContents() = default; ColorSourceContents::~ColorSourceContents() = default; -void ColorSourceContents::SetPath(Path path) { - path_ = path; +void ColorSourceContents::SetGeometry(std::unique_ptr geometry) { + geometry_ = std::move(geometry); } -const Path& ColorSourceContents::GetPath() const { - return path_; +const std::unique_ptr& ColorSourceContents::GetGeometry() const { + return geometry_; } void ColorSourceContents::SetAlpha(Scalar alpha) { @@ -37,17 +37,9 @@ const Matrix& ColorSourceContents::GetInverseMatrix() const { return inverse_matrix_; } -void ColorSourceContents::SetCover(bool cover) { - cover_ = cover; -} - -bool ColorSourceContents::GetCover() const { - return cover_; -} - std::optional ColorSourceContents::GetCoverage( const Entity& entity) const { - return path_.GetTransformedBoundingBox(entity.GetTransformation()); + return geometry_->GetCoverage(entity.GetTransformation()); }; bool ColorSourceContents::ShouldRender( @@ -56,7 +48,7 @@ bool ColorSourceContents::ShouldRender( if (!stencil_coverage.has_value()) { return false; } - return cover_ || Contents::ShouldRender(entity, stencil_coverage); + return Contents::ShouldRender(entity, stencil_coverage); } } // namespace impeller diff --git a/engine/src/flutter/impeller/entity/contents/color_source_contents.h b/engine/src/flutter/impeller/entity/contents/color_source_contents.h index 4e01f46843..f5289192b1 100644 --- a/engine/src/flutter/impeller/entity/contents/color_source_contents.h +++ b/engine/src/flutter/impeller/entity/contents/color_source_contents.h @@ -6,6 +6,7 @@ #include "flutter/fml/macros.h" #include "impeller/entity/contents/contents.h" +#include "impeller/entity/geometry.h" #include "impeller/geometry/matrix.h" #include "impeller/geometry/path.h" @@ -17,14 +18,12 @@ class ColorSourceContents : public Contents { ~ColorSourceContents() override; - void SetPath(Path path); + void SetGeometry(std::unique_ptr geometry); void SetMatrix(Matrix matrix); void SetAlpha(Scalar alpha); - void SetCover(bool cover); - // |Contents| std::optional GetCoverage(const Entity& entity) const override; @@ -33,19 +32,16 @@ class ColorSourceContents : public Contents { const std::optional& stencil_coverage) const override; protected: - const Path& GetPath() const; + const std::unique_ptr& GetGeometry() const; const Matrix& GetInverseMatrix() const; Scalar GetAlpha() const; - bool GetCover() const; - private: - Path path_; + std::unique_ptr geometry_; Matrix inverse_matrix_; Scalar alpha_ = 1.0; - bool cover_ = false; FML_DISALLOW_COPY_AND_ASSIGN(ColorSourceContents); }; diff --git a/engine/src/flutter/impeller/entity/contents/contents.cc b/engine/src/flutter/impeller/entity/contents/contents.cc index 6b96fd45d5..621b644b4f 100644 --- a/engine/src/flutter/impeller/entity/contents/contents.cc +++ b/engine/src/flutter/impeller/entity/contents/contents.cc @@ -78,6 +78,9 @@ bool Contents::ShouldRender(const Entity& entity, if (!coverage.has_value()) { return false; } + if (coverage == Rect::MakeMaximum()) { + return true; + } return stencil_coverage->IntersectsWithRect(coverage.value()); } diff --git a/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents.cc b/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents.cc index efc2627b1c..37855392c3 100644 --- a/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents.cc @@ -229,9 +229,10 @@ static std::optional PipelineBlend( if (foreground_color.has_value()) { auto contents = std::make_shared(); - contents->SetPath(PathBuilder{} - .AddRect(Rect::MakeSize(pass.GetRenderTargetSize())) - .TakePath()); + contents->SetGeometry(Geometry::MakePath( + PathBuilder{} + .AddRect(Rect::MakeSize(pass.GetRenderTargetSize())) + .TakePath())); contents->SetColor(foreground_color.value()); Entity foreground_entity; diff --git a/engine/src/flutter/impeller/entity/contents/linear_gradient_contents.cc b/engine/src/flutter/impeller/entity/contents/linear_gradient_contents.cc index d09692aecf..eef7c5d42f 100644 --- a/engine/src/flutter/impeller/entity/contents/linear_gradient_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/linear_gradient_contents.cc @@ -7,9 +7,7 @@ #include "flutter/fml/logging.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/gradient_generator.h" -#include "impeller/entity/contents/solid_fill_utils.h" #include "impeller/entity/entity.h" -#include "impeller/geometry/path_builder.h" #include "impeller/renderer/formats.h" #include "impeller/renderer/render_pass.h" #include "impeller/renderer/sampler_library.h" @@ -77,13 +75,14 @@ bool LinearGradientContents::Render(const ContentContext& renderer, cmd.pipeline = renderer.GetLinearGradientFillPipeline( OptionsFromPassAndEntity(pass, entity)); cmd.stencil_reference = entity.GetStencilDepth(); - cmd.BindVertices(CreateSolidFillVertices( - renderer.GetTessellator(), - GetCover() - ? PathBuilder{}.AddRect(Size(pass.GetRenderTargetSize())).TakePath() - : GetPath(), - pass.GetTransientsBuffer())); - cmd.primitive_type = PrimitiveType::kTriangle; + + auto& host_buffer = pass.GetTransientsBuffer(); + auto allocator = renderer.GetContext()->GetResourceAllocator(); + auto geometry_result = GetGeometry()->GetPositionBuffer( + allocator, host_buffer, renderer.GetTessellator(), + pass.GetRenderTargetSize()); + cmd.BindVertices(geometry_result.vertex_buffer); + cmd.primitive_type = geometry_result.type; FS::BindGradientInfo( cmd, pass.GetTransientsBuffer().EmplaceUniform(gradient_info)); SamplerDescriptor sampler_desc; diff --git a/engine/src/flutter/impeller/entity/contents/radial_gradient_contents.cc b/engine/src/flutter/impeller/entity/contents/radial_gradient_contents.cc index 8cec68be61..e674ebce19 100644 --- a/engine/src/flutter/impeller/entity/contents/radial_gradient_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/radial_gradient_contents.cc @@ -7,9 +7,8 @@ #include "flutter/fml/logging.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/gradient_generator.h" -#include "impeller/entity/contents/solid_fill_utils.h" #include "impeller/entity/entity.h" -#include "impeller/geometry/path_builder.h" +#include "impeller/entity/geometry.h" #include "impeller/renderer/render_pass.h" #include "impeller/renderer/sampler_library.h" @@ -76,13 +75,13 @@ bool RadialGradientContents::Render(const ContentContext& renderer, cmd.pipeline = renderer.GetRadialGradientFillPipeline( OptionsFromPassAndEntity(pass, entity)); cmd.stencil_reference = entity.GetStencilDepth(); - cmd.BindVertices(CreateSolidFillVertices( - renderer.GetTessellator(), - GetCover() - ? PathBuilder{}.AddRect(Size(pass.GetRenderTargetSize())).TakePath() - : GetPath(), - pass.GetTransientsBuffer())); - cmd.primitive_type = PrimitiveType::kTriangle; + auto& host_buffer = pass.GetTransientsBuffer(); + auto allocator = renderer.GetContext()->GetResourceAllocator(); + auto geometry_result = GetGeometry()->GetPositionBuffer( + allocator, host_buffer, renderer.GetTessellator(), + pass.GetRenderTargetSize()); + cmd.BindVertices(geometry_result.vertex_buffer); + cmd.primitive_type = geometry_result.type; FS::BindGradientInfo( cmd, pass.GetTransientsBuffer().EmplaceUniform(gradient_info)); SamplerDescriptor sampler_desc; diff --git a/engine/src/flutter/impeller/entity/contents/solid_color_contents.cc b/engine/src/flutter/impeller/entity/contents/solid_color_contents.cc index 96c24727c6..bae283cb42 100644 --- a/engine/src/flutter/impeller/entity/contents/solid_color_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/solid_color_contents.cc @@ -5,10 +5,8 @@ #include "solid_color_contents.h" #include "impeller/entity/contents/content_context.h" -#include "impeller/entity/contents/solid_fill_utils.h" #include "impeller/entity/entity.h" #include "impeller/geometry/path.h" -#include "impeller/geometry/path_builder.h" #include "impeller/renderer/render_pass.h" namespace impeller { @@ -25,12 +23,8 @@ const Color& SolidColorContents::GetColor() const { return color_; } -void SolidColorContents::SetPath(Path path) { - path_ = std::move(path); -} - -void SolidColorContents::SetCover(bool cover) { - cover_ = cover; +void SolidColorContents::SetGeometry(std::unique_ptr geometry) { + geometry_ = std::move(geometry); } std::optional SolidColorContents::GetCoverage( @@ -38,7 +32,10 @@ std::optional SolidColorContents::GetCoverage( if (color_.IsTransparent()) { return std::nullopt; } - return path_.GetTransformedBoundingBox(entity.GetTransformation()); + if (geometry_ == nullptr) { + return std::nullopt; + } + return geometry_->GetCoverage(entity.GetTransformation()); }; bool SolidColorContents::ShouldRender( @@ -47,7 +44,7 @@ bool SolidColorContents::ShouldRender( if (!stencil_coverage.has_value()) { return false; } - return cover_ || Contents::ShouldRender(entity, stencil_coverage); + return Contents::ShouldRender(entity, stencil_coverage); } bool SolidColorContents::Render(const ContentContext& renderer, @@ -62,12 +59,13 @@ bool SolidColorContents::Render(const ContentContext& renderer, renderer.GetSolidFillPipeline(OptionsFromPassAndEntity(pass, entity)); cmd.stencil_reference = entity.GetStencilDepth(); - cmd.BindVertices(CreateSolidFillVertices( - renderer.GetTessellator(), - cover_ - ? PathBuilder{}.AddRect(Size(pass.GetRenderTargetSize())).TakePath() - : path_, - pass.GetTransientsBuffer())); + auto& host_buffer = pass.GetTransientsBuffer(); + auto allocator = renderer.GetContext()->GetResourceAllocator(); + auto geometry_result = geometry_->GetPositionBuffer( + allocator, host_buffer, renderer.GetTessellator(), + pass.GetRenderTargetSize()); + cmd.BindVertices(geometry_result.vertex_buffer); + cmd.primitive_type = geometry_result.type; VS::VertInfo vert_info; vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * @@ -78,8 +76,6 @@ bool SolidColorContents::Render(const ContentContext& renderer, frag_info.color = color_.Premultiply(); FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); - cmd.primitive_type = PrimitiveType::kTriangle; - if (!pass.AddCommand(std::move(cmd))) { return false; } @@ -90,7 +86,7 @@ bool SolidColorContents::Render(const ContentContext& renderer, std::unique_ptr SolidColorContents::Make(Path path, Color color) { auto contents = std::make_unique(); - contents->SetPath(std::move(path)); + contents->SetGeometry(Geometry::MakePath(std::move(path))); contents->SetColor(color); return contents; } diff --git a/engine/src/flutter/impeller/entity/contents/solid_color_contents.h b/engine/src/flutter/impeller/entity/contents/solid_color_contents.h index 3ad3d0aa2a..f1c8de81cf 100644 --- a/engine/src/flutter/impeller/entity/contents/solid_color_contents.h +++ b/engine/src/flutter/impeller/entity/contents/solid_color_contents.h @@ -10,6 +10,7 @@ #include "flutter/fml/macros.h" #include "impeller/entity/contents/contents.h" +#include "impeller/entity/geometry.h" #include "impeller/geometry/color.h" #include "impeller/geometry/path.h" @@ -27,9 +28,7 @@ class SolidColorContents final : public Contents { static std::unique_ptr Make(Path path, Color color); - void SetPath(Path path); - - void SetCover(bool cover); + void SetGeometry(std::unique_ptr geometry); void SetColor(Color color); @@ -48,8 +47,7 @@ class SolidColorContents final : public Contents { RenderPass& pass) const override; private: - Path path_; - bool cover_ = false; + std::unique_ptr geometry_; Color color_; diff --git a/engine/src/flutter/impeller/entity/contents/solid_fill_utils.cc b/engine/src/flutter/impeller/entity/contents/solid_fill_utils.cc deleted file mode 100644 index e61e3a55e4..0000000000 --- a/engine/src/flutter/impeller/entity/contents/solid_fill_utils.cc +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "impeller/entity/contents/solid_fill_utils.h" - -#include "impeller/geometry/path.h" -#include "impeller/renderer/device_buffer.h" -#include "impeller/renderer/host_buffer.h" -#include "impeller/tessellator/tessellator.h" - -namespace impeller { - -VertexBuffer CreateSolidFillVertices(std::shared_ptr tessellator, - const Path& path, - HostBuffer& buffer) { - VertexBuffer vertex_buffer; - auto tesselation_result = tessellator->TessellateBuilder( - path.GetFillType(), path.CreatePolyline(), - [&vertex_buffer, &buffer](const float* vertices, size_t vertices_count, - const uint16_t* indices, size_t indices_count) { - vertex_buffer.vertex_buffer = buffer.Emplace( - vertices, vertices_count * sizeof(float), alignof(float)); - vertex_buffer.index_buffer = buffer.Emplace( - indices, indices_count * sizeof(uint16_t), alignof(uint16_t)); - vertex_buffer.index_count = indices_count; - vertex_buffer.index_type = IndexType::k16bit; - return true; - }); - if (tesselation_result != Tessellator::Result::kSuccess) { - return {}; - } - return vertex_buffer; -} - -} // namespace impeller diff --git a/engine/src/flutter/impeller/entity/contents/solid_fill_utils.h b/engine/src/flutter/impeller/entity/contents/solid_fill_utils.h deleted file mode 100644 index 3e55f605ad..0000000000 --- a/engine/src/flutter/impeller/entity/contents/solid_fill_utils.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#pragma once -#include "impeller/renderer/vertex_buffer.h" - -namespace impeller { - -class Tessellator; -class Path; -class HostBuffer; - -/** - * @brief Populate a VertexBuffer with solid fill vertices created by - * tessellating an input path. - * - * @param tessellator The tessellator - * @param path The path to be tessellated - * @param buffer The transient buffer - * @return VertexBuffer A populated vertex buffer if successful, otherwise - * empty. - */ -VertexBuffer CreateSolidFillVertices(std::shared_ptr tessellator, - const Path& path, - HostBuffer& buffer); - -} // namespace impeller diff --git a/engine/src/flutter/impeller/entity/contents/sweep_gradient_contents.cc b/engine/src/flutter/impeller/entity/contents/sweep_gradient_contents.cc index a55d497c3b..2371b6ecfc 100644 --- a/engine/src/flutter/impeller/entity/contents/sweep_gradient_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/sweep_gradient_contents.cc @@ -7,9 +7,7 @@ #include "flutter/fml/logging.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/gradient_generator.h" -#include "impeller/entity/contents/solid_fill_utils.h" #include "impeller/entity/entity.h" -#include "impeller/geometry/path_builder.h" #include "impeller/renderer/render_pass.h" #include "impeller/renderer/sampler_library.h" @@ -83,13 +81,13 @@ bool SweepGradientContents::Render(const ContentContext& renderer, cmd.pipeline = renderer.GetSweepGradientFillPipeline( OptionsFromPassAndEntity(pass, entity)); cmd.stencil_reference = entity.GetStencilDepth(); - cmd.BindVertices(CreateSolidFillVertices( - renderer.GetTessellator(), - GetCover() - ? PathBuilder{}.AddRect(Size(pass.GetRenderTargetSize())).TakePath() - : GetPath(), - pass.GetTransientsBuffer())); - cmd.primitive_type = PrimitiveType::kTriangle; + auto& host_buffer = pass.GetTransientsBuffer(); + auto allocator = renderer.GetContext()->GetResourceAllocator(); + auto geometry_result = GetGeometry()->GetPositionBuffer( + allocator, host_buffer, renderer.GetTessellator(), + pass.GetRenderTargetSize()); + cmd.BindVertices(geometry_result.vertex_buffer); + cmd.primitive_type = geometry_result.type; FS::BindGradientInfo( cmd, pass.GetTransientsBuffer().EmplaceUniform(gradient_info)); VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); diff --git a/engine/src/flutter/impeller/entity/contents/tiled_texture_contents.cc b/engine/src/flutter/impeller/entity/contents/tiled_texture_contents.cc index c9de3101ee..58a535f7c3 100644 --- a/engine/src/flutter/impeller/entity/contents/tiled_texture_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/tiled_texture_contents.cc @@ -5,7 +5,7 @@ #include "impeller/entity/contents/tiled_texture_contents.h" #include "impeller/entity/contents/content_context.h" -#include "impeller/entity/contents/solid_fill_utils.h" +#include "impeller/entity/geometry.h" #include "impeller/entity/tiled_texture_fill.frag.h" #include "impeller/entity/tiled_texture_fill.vert.h" #include "impeller/geometry/path_builder.h" @@ -67,12 +67,12 @@ bool TiledTextureContents::Render(const ContentContext& renderer, cmd.pipeline = renderer.GetTiledTexturePipeline(OptionsFromPassAndEntity(pass, entity)); cmd.stencil_reference = entity.GetStencilDepth(); - cmd.BindVertices(CreateSolidFillVertices( - renderer.GetTessellator(), - GetCover() - ? PathBuilder{}.AddRect(Size(pass.GetRenderTargetSize())).TakePath() - : GetPath(), - host_buffer)); + auto allocator = renderer.GetContext()->GetResourceAllocator(); + auto geometry_result = GetGeometry()->GetPositionBuffer( + allocator, host_buffer, renderer.GetTessellator(), + pass.GetRenderTargetSize()); + cmd.BindVertices(geometry_result.vertex_buffer); + cmd.primitive_type = geometry_result.type; VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); FS::BindTextureSampler(cmd, texture_, diff --git a/engine/src/flutter/impeller/entity/contents/vertices_contents.cc b/engine/src/flutter/impeller/entity/contents/vertices_contents.cc index d5a4bac5e5..31f1f48c53 100644 --- a/engine/src/flutter/impeller/entity/contents/vertices_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/vertices_contents.cc @@ -53,7 +53,8 @@ bool VerticesContents::Render(const ContentContext& renderer, using VS = GeometryColorPipeline::VertexShader; auto geometry_result = geometry_->GetPositionColorBuffer( - allocator, host_buffer, color_, blend_mode_); + allocator, host_buffer, renderer.GetTessellator(), color_, + blend_mode_); cmd.pipeline = renderer.GetGeometryColorPipeline( OptionsFromPassAndEntity(pass, entity)); cmd.primitive_type = geometry_result.type; @@ -69,8 +70,9 @@ bool VerticesContents::Render(const ContentContext& renderer, case GeometryVertexType::kPosition: { using VS = GeometryPositionPipeline::VertexShader; - auto geometry_result = - geometry_->GetPositionBuffer(allocator, host_buffer); + auto geometry_result = geometry_->GetPositionBuffer( + allocator, host_buffer, renderer.GetTessellator(), + pass.GetRenderTargetSize()); cmd.pipeline = renderer.GetGeometryPositionPipeline( OptionsFromPassAndEntity(pass, entity)); cmd.primitive_type = geometry_result.type; diff --git a/engine/src/flutter/impeller/entity/entity_unittests.cc b/engine/src/flutter/impeller/entity/entity_unittests.cc index 58dc2a3980..b5b2e50a6f 100644 --- a/engine/src/flutter/impeller/entity/entity_unittests.cc +++ b/engine/src/flutter/impeller/entity/entity_unittests.cc @@ -294,8 +294,8 @@ TEST_P(EntityTest, StrokeCapAndJoinTest) { auto coverage = entity.GetCoverage(); if (coverage.has_value()) { auto bounds_contents = std::make_unique(); - bounds_contents->SetPath( - PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()); + bounds_contents->SetGeometry(Geometry::MakePath( + PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath())); bounds_contents->SetColor(Color::Green().WithAlpha(0.5)); Entity bounds_entity; bounds_entity.SetContents(std::move(bounds_contents)); @@ -949,7 +949,8 @@ TEST_P(EntityTest, GaussianBlurFilter) { } else { auto fill = std::make_shared(); fill->SetColor(input_color); - fill->SetPath(PathBuilder{}.AddRect(input_rect).TakePath()); + fill->SetGeometry( + Geometry::MakePath(PathBuilder{}.AddRect(input_rect).TakePath())); input = fill; input_size = input_rect.size; @@ -1185,8 +1186,8 @@ TEST_P(EntityTest, SolidStrokeCoverageIsCorrect) { TEST_P(EntityTest, BorderMaskBlurCoverageIsCorrect) { auto fill = std::make_shared(); - fill->SetPath( - PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()); + fill->SetGeometry(Geometry::MakePath( + PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath())); fill->SetColor(Color::CornflowerBlue()); auto border_mask_blur = FilterContents::MakeBorderMaskBlur( FilterInput::Make(fill), Radius{3}, Radius{4}); @@ -1417,7 +1418,8 @@ TEST_P(EntityTest, SolidFillCoverageIsCorrect) { auto fill = std::make_shared(); fill->SetColor(Color::CornflowerBlue()); auto expected = Rect::MakeLTRB(100, 110, 200, 220); - fill->SetPath(PathBuilder{}.AddRect(expected).TakePath()); + fill->SetGeometry( + Geometry::MakePath(PathBuilder{}.AddRect(expected).TakePath())); auto coverage = fill->GetCoverage({}); ASSERT_TRUE(coverage.has_value()); @@ -1428,8 +1430,8 @@ TEST_P(EntityTest, SolidFillCoverageIsCorrect) { { auto fill = std::make_shared(); fill->SetColor(Color::CornflowerBlue()); - fill->SetPath( - PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()); + fill->SetGeometry(Geometry::MakePath( + PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath())); Entity entity; entity.SetTransformation(Matrix::MakeTranslation(Vector2(4, 5))); @@ -1445,8 +1447,8 @@ TEST_P(EntityTest, SolidFillCoverageIsCorrect) { { auto fill = std::make_shared(); fill->SetColor(Color::WhiteTransparent()); - fill->SetPath( - PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()); + fill->SetGeometry(Geometry::MakePath( + PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath())); auto coverage = fill->GetCoverage({}); ASSERT_FALSE(coverage.has_value()); @@ -1467,8 +1469,8 @@ TEST_P(EntityTest, SolidFillShouldRenderIsCorrect) { { auto fill = std::make_shared(); fill->SetColor(Color::CornflowerBlue()); - fill->SetPath( - PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()); + fill->SetGeometry(Geometry::MakePath( + PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath())); ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100}))); ASSERT_FALSE( fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50))); @@ -1478,7 +1480,7 @@ TEST_P(EntityTest, SolidFillShouldRenderIsCorrect) { { auto fill = std::make_shared(); fill->SetColor(Color::CornflowerBlue()); - fill->SetCover(true); + fill->SetGeometry(Geometry::MakeCover()); ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100}))); ASSERT_TRUE( fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50))); @@ -1492,8 +1494,8 @@ TEST_P(EntityTest, ClipContentsShouldRenderIsCorrect) { { auto clip = std::make_shared(); ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100}))); - clip->SetPath( - PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()); + clip->SetGeometry(Geometry::MakePath( + PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath())); ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100}))); ASSERT_TRUE( clip->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50))); @@ -1552,8 +1554,8 @@ TEST_P(EntityTest, RRectShadowTest) { auto coverage = entity.GetCoverage(); if (show_coverage && coverage.has_value()) { auto bounds_contents = std::make_unique(); - bounds_contents->SetPath( - PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()); + bounds_contents->SetGeometry(Geometry::MakePath( + PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath())); bounds_contents->SetColor(coverage_color.Premultiply()); Entity bounds_entity; bounds_entity.SetContents(std::move(bounds_contents)); @@ -1568,8 +1570,8 @@ TEST_P(EntityTest, RRectShadowTest) { TEST_P(EntityTest, ColorMatrixFilterCoverageIsCorrect) { // Set up a simple color background. auto fill = std::make_shared(); - fill->SetPath( - PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()); + fill->SetGeometry(Geometry::MakePath( + PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath())); fill->SetColor(Color::Coral()); // Set the color matrix filter. @@ -1662,8 +1664,8 @@ TEST_P(EntityTest, ColorMatrixFilterEditable) { TEST_P(EntityTest, LinearToSrgbFilterCoverageIsCorrect) { // Set up a simple color background. auto fill = std::make_shared(); - fill->SetPath( - PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()); + fill->SetGeometry(Geometry::MakePath( + PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath())); fill->SetColor(Color::MintCream()); auto filter = FilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill)); @@ -1713,8 +1715,8 @@ TEST_P(EntityTest, LinearToSrgbFilter) { TEST_P(EntityTest, SrgbToLinearFilterCoverageIsCorrect) { // Set up a simple color background. auto fill = std::make_shared(); - fill->SetPath( - PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()); + fill->SetGeometry(Geometry::MakePath( + PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath())); fill->SetColor(Color::DeepPink()); auto filter = FilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill)); diff --git a/engine/src/flutter/impeller/entity/geometry.cc b/engine/src/flutter/impeller/entity/geometry.cc index 73776c6348..5cbaf2707e 100644 --- a/engine/src/flutter/impeller/entity/geometry.cc +++ b/engine/src/flutter/impeller/entity/geometry.cc @@ -5,7 +5,9 @@ #include "impeller/entity/geometry.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/position_color.vert.h" +#include "impeller/geometry/path_builder.h" #include "impeller/renderer/device_buffer.h" +#include "impeller/tessellator/tessellator.h" namespace impeller { @@ -18,6 +20,16 @@ std::unique_ptr Geometry::MakeVertices(Vertices vertices) { return std::make_unique(std::move(vertices)); } +std::unique_ptr Geometry::MakePath(Path path) { + return std::make_unique(std::move(path)); +} + +std::unique_ptr Geometry::MakeCover() { + return std::make_unique(); +} + +/////// Vertices Geometry /////// + VerticesGeometry::VerticesGeometry(Vertices vertices) : vertices_(std::move(vertices)) {} @@ -34,7 +46,9 @@ static PrimitiveType GetPrimitiveType(const Vertices& vertices) { GeometryResult VerticesGeometry::GetPositionBuffer( std::shared_ptr device_allocator, - HostBuffer& host_buffer) { + HostBuffer& host_buffer, + std::shared_ptr tessellator, + ISize render_target_size) { if (!vertices_.IsValid()) { return {}; } @@ -80,6 +94,7 @@ GeometryResult VerticesGeometry::GetPositionBuffer( GeometryResult VerticesGeometry::GetPositionColorBuffer( std::shared_ptr device_allocator, HostBuffer& host_buffer, + std::shared_ptr tessellator, Color paint_color, BlendMode blend_mode) { using VS = GeometryColorPipeline::VertexShader; @@ -140,6 +155,7 @@ GeometryResult VerticesGeometry::GetPositionColorBuffer( GeometryResult VerticesGeometry::GetPositionUVBuffer( std::shared_ptr device_allocator, HostBuffer& host_buffer, + std::shared_ptr tessellator, ISize render_target_size) { // TODO(jonahwilliams): support texture coordinates in vertices. return {}; @@ -156,4 +172,120 @@ std::optional VerticesGeometry::GetCoverage(Matrix transform) { return vertices_.GetTransformedBoundingBox(transform); } +/////// Path Geometry /////// + +PathGeometry::PathGeometry(Path path) : path_(std::move(path)) {} + +PathGeometry::~PathGeometry() = default; + +GeometryResult PathGeometry::GetPositionBuffer( + std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + ISize render_target_size) { + VertexBuffer vertex_buffer; + auto tesselation_result = tessellator->TessellateBuilder( + path_.GetFillType(), path_.CreatePolyline(), + [&vertex_buffer, &host_buffer]( + const float* vertices, size_t vertices_count, const uint16_t* indices, + size_t indices_count) { + vertex_buffer.vertex_buffer = host_buffer.Emplace( + vertices, vertices_count * sizeof(float), alignof(float)); + vertex_buffer.index_buffer = host_buffer.Emplace( + indices, indices_count * sizeof(uint16_t), alignof(uint16_t)); + vertex_buffer.index_count = indices_count; + vertex_buffer.index_type = IndexType::k16bit; + return true; + }); + if (tesselation_result != Tessellator::Result::kSuccess) { + return {}; + } + return GeometryResult{ + .type = PrimitiveType::kTriangle, + .vertex_buffer = vertex_buffer, + .prevent_overdraw = false, + }; +} + +GeometryResult PathGeometry::GetPositionColorBuffer( + std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + Color paint_color, + BlendMode blend_mode) { + // TODO(jonahwilliams): support per-color vertex in path geometry. + return {}; +} + +GeometryResult PathGeometry::GetPositionUVBuffer( + std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + ISize render_target_size) { + // TODO(jonahwilliams): support texture coordinates in path geometry. + return {}; +} + +GeometryVertexType PathGeometry::GetVertexType() { + return GeometryVertexType::kPosition; +} + +std::optional PathGeometry::GetCoverage(Matrix transform) { + return path_.GetTransformedBoundingBox(transform); +} + +/////// Cover Geometry /////// + +CoverGeometry::CoverGeometry() = default; + +CoverGeometry::~CoverGeometry() = default; + +GeometryResult CoverGeometry::GetPositionBuffer( + std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + ISize render_target_size) { + auto rect = Rect(Size(render_target_size)); + constexpr uint16_t kRectIndicies[4] = {0, 1, 2, 3}; + 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 CoverGeometry::GetPositionColorBuffer( + std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + Color paint_color, + BlendMode blend_mode) { + // TODO(jonahwilliams): support per-color vertex in cover geometry. + return {}; +} + +GeometryResult CoverGeometry::GetPositionUVBuffer( + std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + ISize render_target_size) { + // TODO(jonahwilliams): support texture coordinates in cover geometry. + return {}; +} + +GeometryVertexType CoverGeometry::GetVertexType() { + return GeometryVertexType::kPosition; +} + +std::optional CoverGeometry::GetCoverage(Matrix transform) { + return Rect::MakeMaximum(); +} + } // namespace impeller diff --git a/engine/src/flutter/impeller/entity/geometry.h b/engine/src/flutter/impeller/entity/geometry.h index a6f63d9844..293140d2a2 100644 --- a/engine/src/flutter/impeller/entity/geometry.h +++ b/engine/src/flutter/impeller/entity/geometry.h @@ -13,6 +13,8 @@ namespace impeller { +class Tessellator; + struct GeometryResult { PrimitiveType type; VertexBuffer vertex_buffer; @@ -33,19 +35,27 @@ class Geometry { static std::unique_ptr MakeVertices(Vertices vertices); + static std::unique_ptr MakePath(Path path); + + static std::unique_ptr MakeCover(); + virtual GeometryResult GetPositionBuffer( std::shared_ptr device_allocator, - HostBuffer& host_buffer) = 0; + HostBuffer& host_buffer, + std::shared_ptr tessellator, + ISize render_target_size) = 0; virtual GeometryResult GetPositionColorBuffer( std::shared_ptr device_allocator, HostBuffer& host_buffer, + std::shared_ptr tessellator, Color paint_color, BlendMode blend_mode) = 0; virtual GeometryResult GetPositionUVBuffer( std::shared_ptr device_allocator, HostBuffer& host_buffer, + std::shared_ptr tessellator, ISize render_target_size) = 0; virtual GeometryVertexType GetVertexType() = 0; @@ -53,6 +63,7 @@ class Geometry { virtual std::optional GetCoverage(Matrix transform) = 0; }; +/// @brief A geometry that is created from a vertices object. class VerticesGeometry : public Geometry { public: VerticesGeometry(Vertices vertices); @@ -62,12 +73,15 @@ class VerticesGeometry : public Geometry { private: // |Geometry| GeometryResult GetPositionBuffer(std::shared_ptr device_allocator, - HostBuffer& host_buffer) override; + HostBuffer& host_buffer, + std::shared_ptr tessellator, + ISize render_target_size) override; // |Geometry| GeometryResult GetPositionColorBuffer( std::shared_ptr device_allocator, HostBuffer& host_buffer, + std::shared_ptr tessellator, Color paint_color, BlendMode blend_mode) override; @@ -75,6 +89,7 @@ class VerticesGeometry : public Geometry { GeometryResult GetPositionUVBuffer( std::shared_ptr device_allocator, HostBuffer& host_buffer, + std::shared_ptr tessellator, ISize render_target_size) override; // |Geometry| @@ -88,4 +103,83 @@ class VerticesGeometry : public Geometry { FML_DISALLOW_COPY_AND_ASSIGN(VerticesGeometry); }; +/// @brief A geometry that is created from a path object. +class PathGeometry : public Geometry { + public: + PathGeometry(Path path); + + ~PathGeometry(); + + private: + // |Geometry| + GeometryResult GetPositionBuffer(std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + ISize render_target_size) override; + + // |Geometry| + GeometryResult GetPositionColorBuffer( + std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + Color paint_color, + BlendMode blend_mode) override; + + // |Geometry| + GeometryResult GetPositionUVBuffer( + std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + ISize render_target_size) override; + + // |Geometry| + GeometryVertexType GetVertexType() override; + + // |Geometry| + std::optional GetCoverage(Matrix transform) override; + + Path path_; + + FML_DISALLOW_COPY_AND_ASSIGN(PathGeometry); +}; + +/// @brief A geometry that implements "drawPaint" like behavior by covering +/// the entire render pass area. +class CoverGeometry : public Geometry { + public: + CoverGeometry(); + + ~CoverGeometry(); + + private: + // |Geometry| + GeometryResult GetPositionBuffer(std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + ISize render_target_size) override; + + // |Geometry| + GeometryResult GetPositionColorBuffer( + std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + Color paint_color, + BlendMode blend_mode) override; + + // |Geometry| + GeometryResult GetPositionUVBuffer( + std::shared_ptr device_allocator, + HostBuffer& host_buffer, + std::shared_ptr tessellator, + ISize render_target_size) override; + + // |Geometry| + GeometryVertexType GetVertexType() override; + + // |Geometry| + std::optional GetCoverage(Matrix transform) override; + + FML_DISALLOW_COPY_AND_ASSIGN(CoverGeometry); +}; + } // namespace impeller diff --git a/engine/src/flutter/impeller/geometry/rect.h b/engine/src/flutter/impeller/geometry/rect.h index 8b0a169d02..803000bc00 100644 --- a/engine/src/flutter/impeller/geometry/rect.h +++ b/engine/src/flutter/impeller/geometry/rect.h @@ -73,6 +73,13 @@ struct TRect { return TRect::MakeLTRB(left, top, right, bottom); } + constexpr static TRect MakeMaximum() { + return TRect::MakeLTRB(-std::numeric_limits::infinity(), + -std::numeric_limits::infinity(), + std::numeric_limits::infinity(), + std::numeric_limits::infinity()); + } + template constexpr explicit TRect(const TRect& other) : origin(static_cast>(other.origin)),