From 4ada719010531922d5447491d4a5419284afbf70 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 8 Nov 2023 18:08:04 -0800 Subject: [PATCH 1/9] [Impeller] faster path for drawCircle. --- impeller/aiks/canvas.cc | 16 ++- impeller/entity/BUILD.gn | 4 +- impeller/entity/entity_unittests.cc | 34 ++--- ...t_field_geometry.cc => circle_geometry.cc} | 119 +++++++++++++----- ...int_field_geometry.h => circle_geometry.h} | 21 ++-- impeller/entity/geometry/geometry.cc | 6 +- impeller/entity/geometry/geometry.h | 6 +- 7 files changed, 142 insertions(+), 64 deletions(-) rename impeller/entity/geometry/{point_field_geometry.cc => circle_geometry.cc} (71%) rename impeller/entity/geometry/{point_field_geometry.h => circle_geometry.h} (70%) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index a0823f912de98..f79d60f8238d2 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -277,6 +277,18 @@ void Canvas::DrawCircle(Point center, Scalar radius, const Paint& paint) { paint)) { return; } + if (paint.style == Paint::Style::kFill) { + Entity entity; + entity.SetTransformation(GetCurrentTransformation()); + entity.SetClipDepth(GetClipDepth()); + entity.SetBlendMode(paint.blend_mode); + entity.SetContents(paint.WithFilters(paint.CreateContentsForGeometry( + Geometry::MakeCircle({center}, radius, true)))); + + GetCurrentPass().AddEntity(entity); + return; + } + auto circle_path = PathBuilder{} .AddCircle(center, radius) @@ -434,8 +446,8 @@ void Canvas::DrawPoints(std::vector points, entity.SetClipDepth(GetClipDepth()); entity.SetBlendMode(paint.blend_mode); entity.SetContents(paint.WithFilters(paint.CreateContentsForGeometry( - Geometry::MakePointField(std::move(points), radius, - /*round=*/point_style == PointStyle::kRound)))); + Geometry::MakeCircle(std::move(points), radius, + /*round=*/point_style == PointStyle::kRound)))); GetCurrentPass().AddEntity(entity); } diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 2460a19178513..787ba728c354a 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -194,8 +194,8 @@ impeller_component("entity") { "geometry/fill_path_geometry.h", "geometry/geometry.cc", "geometry/geometry.h", - "geometry/point_field_geometry.cc", - "geometry/point_field_geometry.h", + "geometry/circle_geometry.cc", + "geometry/circle_geometry.h", "geometry/rect_geometry.cc", "geometry/rect_geometry.h", "geometry/stroke_path_geometry.cc", diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index ea564dfa8e029..4e9ebf4b3b706 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -31,7 +31,7 @@ #include "impeller/entity/entity_pass_delegate.h" #include "impeller/entity/entity_playground.h" #include "impeller/entity/geometry/geometry.h" -#include "impeller/entity/geometry/point_field_geometry.h" +#include "impeller/entity/geometry/circle_geometry.h" #include "impeller/entity/geometry/stroke_path_geometry.h" #include "impeller/geometry/color.h" #include "impeller/geometry/geometry_asserts.h" @@ -2390,27 +2390,27 @@ TEST_P(EntityTest, TessellateConvex) { } } -TEST_P(EntityTest, PointFieldGeometryDivisions) { +TEST_P(EntityTest, CircleGeometryDivisions) { // Square always gives 4 divisions. - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(24.0, false), 4u); - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(2.0, false), 4u); - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(200.0, false), 4u); - - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(0.5, true), 4u); - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1.5, true), 8u); - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(5.5, true), 24u); - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(12.5, true), 34u); - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(22.3, true), 22u); - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(40.5, true), 40u); - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(100.0, true), 100u); + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(24.0, false), 4u); + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(2.0, false), 4u); + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(200.0, false), 4u); + + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(0.5, true), 4u); + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(1.5, true), 8u); + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(5.5, true), 24u); + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(12.5, true), 34u); + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(22.3, true), 22u); + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(40.5, true), 40u); + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(100.0, true), 100u); // Caps at 140. - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1000.0, true), 140u); - ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(20000.0, true), 140u); + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(1000.0, true), 140u); + ASSERT_EQ(CircleGeometry::ComputeCircleDivisions(20000.0, true), 140u); } -TEST_P(EntityTest, PointFieldGeometryCoverage) { +TEST_P(EntityTest, CircleGeometryCoverage) { std::vector points = {{10, 20}, {100, 200}}; - auto geometry = Geometry::MakePointField(points, 5.0, false); + auto geometry = Geometry::MakeCircle(points, 5.0, false); ASSERT_EQ(*geometry->GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205)); ASSERT_EQ(*geometry->GetCoverage(Matrix::MakeTranslation({30, 0, 0})), Rect::MakeLTRB(35, 15, 135, 205)); diff --git a/impeller/entity/geometry/point_field_geometry.cc b/impeller/entity/geometry/circle_geometry.cc similarity index 71% rename from impeller/entity/geometry/point_field_geometry.cc rename to impeller/entity/geometry/circle_geometry.cc index 9821bad91ad7b..ac6f603da6ae1 100644 --- a/impeller/entity/geometry/point_field_geometry.cc +++ b/impeller/entity/geometry/circle_geometry.cc @@ -2,54 +2,54 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "impeller/entity/geometry/point_field_geometry.h" +#include "impeller/entity/geometry/circle_geometry.h" #include "impeller/renderer/command_buffer.h" #include "impeller/renderer/compute_command.h" namespace impeller { -PointFieldGeometry::PointFieldGeometry(std::vector points, - Scalar radius, - bool round) +// The minimum number of points before compute is used to fill out the geometry. +// This number was arbitrarily chosen. +static constexpr size_t kMinComputeSize = 32; + +CircleGeometry::CircleGeometry(std::vector points, + Scalar radius, + bool round) : points_(std::move(points)), radius_(radius), round_(round) {} -PointFieldGeometry::~PointFieldGeometry() = default; +CircleGeometry::~CircleGeometry() = default; -GeometryResult PointFieldGeometry::GetPositionBuffer( - const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) { - if (renderer.GetDeviceCapabilities().SupportsCompute()) { +GeometryResult CircleGeometry::GetPositionBuffer(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) { + if (points_.size() > kMinComputeSize && + renderer.GetDeviceCapabilities().SupportsCompute()) { return GetPositionBufferGPU(renderer, entity, pass); } - auto vtx_builder = GetPositionBufferCPU(renderer, entity, pass); - if (!vtx_builder.has_value()) { - return {}; - } - auto& host_buffer = pass.GetTransientsBuffer(); return { .type = PrimitiveType::kTriangle, - .vertex_buffer = vtx_builder->CreateVertexBuffer(host_buffer), + .vertex_buffer = GetPositionBufferCPU(renderer, entity, pass), .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), .prevent_overdraw = false, }; } -GeometryResult PointFieldGeometry::GetPositionUVBuffer( +GeometryResult CircleGeometry::GetPositionUVBuffer( Rect texture_coverage, Matrix effect_transform, const ContentContext& renderer, const Entity& entity, RenderPass& pass) { - if (renderer.GetDeviceCapabilities().SupportsCompute()) { + if (points_.size() > kMinComputeSize && + renderer.GetDeviceCapabilities().SupportsCompute()) { return GetPositionBufferGPU(renderer, entity, pass, texture_coverage, effect_transform); } - auto vtx_builder = GetPositionBufferCPU(renderer, entity, pass); + auto vtx_builder = GetPositionUVBufferCPU(renderer, entity, pass); if (!vtx_builder.has_value()) { return {}; } @@ -66,10 +66,74 @@ GeometryResult PointFieldGeometry::GetPositionUVBuffer( }; } +VertexBuffer CircleGeometry::GetPositionBufferCPU( + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) { + if (radius_ < 0.0) { + return {}; + } + auto determinant = entity.GetTransformation().GetDeterminant(); + if (determinant == 0) { + return {}; + } + + Scalar min_size = 1.0f / sqrt(std::abs(determinant)); + Scalar radius = std::max(radius_, min_size); + + auto vertices_per_geom = ComputeCircleDivisions( + entity.GetTransformation().GetMaxBasisLength() * radius, round_); + auto points_per_circle = 3 + (vertices_per_geom - 3) * 3; + auto total = points_per_circle * points_.size(); + auto radian_start = round_ ? 0.0f : 0.785398f; + auto radian_step = k2Pi / vertices_per_geom; + + auto& host_buffer = pass.GetTransientsBuffer(); + + /// Precompute all relative points and angles for a fixed geometry size. + auto elapsed_angle = radian_start; + std::vector angle_table(vertices_per_geom); + for (auto i = 0u; i < vertices_per_geom; i++) { + angle_table[i] = Point(cos(elapsed_angle), sin(elapsed_angle)) * radius; + elapsed_angle += radian_step; + } + + auto vertex_buffer = host_buffer.Emplace( + total * sizeof(Point), alignof(Point), [&](uint8_t* buffer) { + Point* points = reinterpret_cast(buffer); + auto offset = 0u; + for (auto i = 0u; i < points_.size(); i++) { + auto center = points_[i]; + + auto origin = center + angle_table[0]; + points[offset++] = origin; + + auto pt1 = center + angle_table[1]; + points[offset++] = pt1; + + auto pt2 = center + angle_table[2]; + points[offset++] = pt2; + + for (auto j = 0u; j < vertices_per_geom - 3; j++) { + points[offset++] = origin; + points[offset++] = pt2; + pt2 = center + angle_table[j + 3]; + points[offset++] = pt2; + } + } + }); + + return VertexBuffer{ + .vertex_buffer = vertex_buffer, + .vertex_count = total, + .index_type = IndexType::kNone, + }; +} + std::optional> -PointFieldGeometry::GetPositionBufferCPU(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) { +CircleGeometry::GetPositionUVBufferCPU(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) { if (radius_ < 0.0) { return std::nullopt; } @@ -122,7 +186,7 @@ PointFieldGeometry::GetPositionBufferCPU(const ContentContext& renderer, return vtx_builder; } -GeometryResult PointFieldGeometry::GetPositionBufferGPU( +GeometryResult CircleGeometry::GetPositionBufferGPU( const ContentContext& renderer, const Entity& entity, RenderPass& pass, @@ -241,8 +305,8 @@ GeometryResult PointFieldGeometry::GetPositionBufferGPU( /// @brief Compute the number of vertices to divide each circle into. /// /// @return the number of vertices. -size_t PointFieldGeometry::ComputeCircleDivisions(Scalar scaled_radius, - bool round) { +size_t CircleGeometry::ComputeCircleDivisions(Scalar scaled_radius, + bool round) { if (!round) { return 4; } @@ -265,13 +329,12 @@ size_t PointFieldGeometry::ComputeCircleDivisions(Scalar scaled_radius, } // |Geometry| -GeometryVertexType PointFieldGeometry::GetVertexType() const { +GeometryVertexType CircleGeometry::GetVertexType() const { return GeometryVertexType::kPosition; } // |Geometry| -std::optional PointFieldGeometry::GetCoverage( - const Matrix& transform) const { +std::optional CircleGeometry::GetCoverage(const Matrix& transform) const { if (points_.size() > 0) { // Doesn't use MakePointBounds as this isn't resilient to points that // all lie along the same axis. diff --git a/impeller/entity/geometry/point_field_geometry.h b/impeller/entity/geometry/circle_geometry.h similarity index 70% rename from impeller/entity/geometry/point_field_geometry.h rename to impeller/entity/geometry/circle_geometry.h index 30ccdaa01a369..27623d58cb2b5 100644 --- a/impeller/entity/geometry/point_field_geometry.h +++ b/impeller/entity/geometry/circle_geometry.h @@ -8,11 +8,11 @@ namespace impeller { -class PointFieldGeometry : public Geometry { +class CircleGeometry : public Geometry { public: - PointFieldGeometry(std::vector points, Scalar radius, bool round); + CircleGeometry(std::vector points, Scalar radius, bool round); - ~PointFieldGeometry(); + ~CircleGeometry(); static size_t ComputeCircleDivisions(Scalar scaled_radius, bool round); @@ -42,18 +42,21 @@ class PointFieldGeometry : public Geometry { std::optional texture_coverage = std::nullopt, std::optional effect_transform = std::nullopt); - std::optional> - GetPositionBufferCPU(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass); + VertexBuffer GetPositionBufferCPU(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass); + + std::optional> GetPositionUVBufferCPU(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass); std::vector points_; Scalar radius_; bool round_; - PointFieldGeometry(const PointFieldGeometry&) = delete; + CircleGeometry(const CircleGeometry&) = delete; - PointFieldGeometry& operator=(const PointFieldGeometry&) = delete; + CircleGeometry& operator=(const CircleGeometry&) = delete; }; } // namespace impeller diff --git a/impeller/entity/geometry/geometry.cc b/impeller/entity/geometry/geometry.cc index 29d880a86c86b..e306414fc1f9b 100644 --- a/impeller/entity/geometry/geometry.cc +++ b/impeller/entity/geometry/geometry.cc @@ -8,7 +8,7 @@ #include "impeller/entity/geometry/cover_geometry.h" #include "impeller/entity/geometry/fill_path_geometry.h" -#include "impeller/entity/geometry/point_field_geometry.h" +#include "impeller/entity/geometry/circle_geometry.h" #include "impeller/entity/geometry/rect_geometry.h" #include "impeller/entity/geometry/stroke_path_geometry.h" #include "impeller/geometry/rect.h" @@ -117,10 +117,10 @@ std::unique_ptr Geometry::MakeFillPath( return std::make_unique(path, inner_rect); } -std::unique_ptr Geometry::MakePointField(std::vector points, +std::unique_ptr Geometry::MakeCircle(std::vector points, Scalar radius, bool round) { - return std::make_unique(std::move(points), radius, round); + return std::make_unique(std::move(points), radius, round); } std::unique_ptr Geometry::MakeStrokePath(const Path& path, diff --git a/impeller/entity/geometry/geometry.h b/impeller/entity/geometry/geometry.h index c0743626953ae..e0609df755f13 100644 --- a/impeller/entity/geometry/geometry.h +++ b/impeller/entity/geometry/geometry.h @@ -72,9 +72,9 @@ class Geometry { static std::unique_ptr MakeRect(Rect rect); - static std::unique_ptr MakePointField(std::vector points, - Scalar radius, - bool round); + static std::unique_ptr MakeCircle(std::vector points, + Scalar radius, + bool round); virtual GeometryResult GetPositionBuffer(const ContentContext& renderer, const Entity& entity, From 4fa541e8557d5cd3745e2eea59af78b0deb714c4 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 8 Nov 2023 18:08:54 -0800 Subject: [PATCH 2/9] ++ --- impeller/entity/BUILD.gn | 4 ++-- impeller/entity/entity_unittests.cc | 2 +- impeller/entity/geometry/circle_geometry.h | 7 ++++--- impeller/entity/geometry/geometry.cc | 6 +++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 787ba728c354a..33b778e905559 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -188,14 +188,14 @@ impeller_component("entity") { "entity_pass_delegate.h", "entity_pass_target.cc", "entity_pass_target.h", + "geometry/circle_geometry.cc", + "geometry/circle_geometry.h", "geometry/cover_geometry.cc", "geometry/cover_geometry.h", "geometry/fill_path_geometry.cc", "geometry/fill_path_geometry.h", "geometry/geometry.cc", "geometry/geometry.h", - "geometry/circle_geometry.cc", - "geometry/circle_geometry.h", "geometry/rect_geometry.cc", "geometry/rect_geometry.h", "geometry/stroke_path_geometry.cc", diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 4e9ebf4b3b706..6e2429c5f20dd 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -30,8 +30,8 @@ #include "impeller/entity/entity_pass.h" #include "impeller/entity/entity_pass_delegate.h" #include "impeller/entity/entity_playground.h" -#include "impeller/entity/geometry/geometry.h" #include "impeller/entity/geometry/circle_geometry.h" +#include "impeller/entity/geometry/geometry.h" #include "impeller/entity/geometry/stroke_path_geometry.h" #include "impeller/geometry/color.h" #include "impeller/geometry/geometry_asserts.h" diff --git a/impeller/entity/geometry/circle_geometry.h b/impeller/entity/geometry/circle_geometry.h index 27623d58cb2b5..3264b5e0f50e4 100644 --- a/impeller/entity/geometry/circle_geometry.h +++ b/impeller/entity/geometry/circle_geometry.h @@ -46,9 +46,10 @@ class CircleGeometry : public Geometry { const Entity& entity, RenderPass& pass); - std::optional> GetPositionUVBufferCPU(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass); + std::optional> + GetPositionUVBufferCPU(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass); std::vector points_; Scalar radius_; diff --git a/impeller/entity/geometry/geometry.cc b/impeller/entity/geometry/geometry.cc index e306414fc1f9b..0c3047a5b5f79 100644 --- a/impeller/entity/geometry/geometry.cc +++ b/impeller/entity/geometry/geometry.cc @@ -6,9 +6,9 @@ #include +#include "impeller/entity/geometry/circle_geometry.h" #include "impeller/entity/geometry/cover_geometry.h" #include "impeller/entity/geometry/fill_path_geometry.h" -#include "impeller/entity/geometry/circle_geometry.h" #include "impeller/entity/geometry/rect_geometry.h" #include "impeller/entity/geometry/stroke_path_geometry.h" #include "impeller/geometry/rect.h" @@ -118,8 +118,8 @@ std::unique_ptr Geometry::MakeFillPath( } std::unique_ptr Geometry::MakeCircle(std::vector points, - Scalar radius, - bool round) { + Scalar radius, + bool round) { return std::make_unique(std::move(points), radius, round); } From 28eed8a8f3fd9562afbc3463803b64ed284d5c0c Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 8 Nov 2023 18:48:26 -0800 Subject: [PATCH 3/9] ++ --- ci/licenses_golden/licenses_flutter | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 605d139cef36f..c68cdbaff43b1 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -3118,14 +3118,14 @@ ORIGIN: ../../../flutter/impeller/entity/entity_pass_target.cc + ../../../flutte ORIGIN: ../../../flutter/impeller/entity/entity_pass_target.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/entity_playground.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/entity_playground.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/geometry/circle_geometry.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/geometry/circle_geometry.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry/cover_geometry.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry/cover_geometry.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry/fill_path_geometry.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry/fill_path_geometry.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry/geometry.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry/geometry.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/geometry/point_field_geometry.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/geometry/point_field_geometry.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry/rect_geometry.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry/rect_geometry.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry/stroke_path_geometry.cc + ../../../flutter/LICENSE @@ -5875,14 +5875,14 @@ FILE: ../../../flutter/impeller/entity/entity_pass_target.cc FILE: ../../../flutter/impeller/entity/entity_pass_target.h FILE: ../../../flutter/impeller/entity/entity_playground.cc FILE: ../../../flutter/impeller/entity/entity_playground.h +FILE: ../../../flutter/impeller/entity/geometry/circle_geometry.cc +FILE: ../../../flutter/impeller/entity/geometry/circle_geometry.h FILE: ../../../flutter/impeller/entity/geometry/cover_geometry.cc FILE: ../../../flutter/impeller/entity/geometry/cover_geometry.h FILE: ../../../flutter/impeller/entity/geometry/fill_path_geometry.cc FILE: ../../../flutter/impeller/entity/geometry/fill_path_geometry.h FILE: ../../../flutter/impeller/entity/geometry/geometry.cc FILE: ../../../flutter/impeller/entity/geometry/geometry.h -FILE: ../../../flutter/impeller/entity/geometry/point_field_geometry.cc -FILE: ../../../flutter/impeller/entity/geometry/point_field_geometry.h FILE: ../../../flutter/impeller/entity/geometry/rect_geometry.cc FILE: ../../../flutter/impeller/entity/geometry/rect_geometry.h FILE: ../../../flutter/impeller/entity/geometry/stroke_path_geometry.cc From 4ecec73ef60e83bd5bf9d03c8738233f9088458a Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 9 Nov 2023 14:07:15 -0800 Subject: [PATCH 4/9] ++ --- impeller/entity/geometry/circle_geometry.cc | 52 ++++++-------------- impeller/entity/shaders/geometry/points.comp | 31 ++++-------- 2 files changed, 24 insertions(+), 59 deletions(-) diff --git a/impeller/entity/geometry/circle_geometry.cc b/impeller/entity/geometry/circle_geometry.cc index ac6f603da6ae1..99fc17c7770e8 100644 --- a/impeller/entity/geometry/circle_geometry.cc +++ b/impeller/entity/geometry/circle_geometry.cc @@ -29,7 +29,7 @@ GeometryResult CircleGeometry::GetPositionBuffer(const ContentContext& renderer, } return { - .type = PrimitiveType::kTriangle, + .type = PrimitiveType::kTriangleStrip, .vertex_buffer = GetPositionBufferCPU(renderer, entity, pass), .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), @@ -58,7 +58,7 @@ GeometryResult CircleGeometry::GetPositionUVBuffer( auto& host_buffer = pass.GetTransientsBuffer(); return { - .type = PrimitiveType::kTriangle, + .type = PrimitiveType::kTriangleStrip, .vertex_buffer = uv_vtx_builder.CreateVertexBuffer(host_buffer), .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), @@ -83,7 +83,8 @@ VertexBuffer CircleGeometry::GetPositionBufferCPU( auto vertices_per_geom = ComputeCircleDivisions( entity.GetTransformation().GetMaxBasisLength() * radius, round_); - auto points_per_circle = 3 + (vertices_per_geom - 3) * 3; + + auto points_per_circle = vertices_per_geom * 2 + 1; auto total = points_per_circle * points_.size(); auto radian_start = round_ ? 0.0f : 0.785398f; auto radian_step = k2Pi / vertices_per_geom; @@ -104,22 +105,11 @@ VertexBuffer CircleGeometry::GetPositionBufferCPU( auto offset = 0u; for (auto i = 0u; i < points_.size(); i++) { auto center = points_[i]; - - auto origin = center + angle_table[0]; - points[offset++] = origin; - - auto pt1 = center + angle_table[1]; - points[offset++] = pt1; - - auto pt2 = center + angle_table[2]; - points[offset++] = pt2; - - for (auto j = 0u; j < vertices_per_geom - 3; j++) { - points[offset++] = origin; - points[offset++] = pt2; - pt2 = center + angle_table[j + 3]; - points[offset++] = pt2; + for (auto j = 0u; j < vertices_per_geom; j++) { + points[offset++] = center + angle_table[j]; + points[offset++] = center; } + points[offset++] = center + angle_table[0]; } }); @@ -147,7 +137,7 @@ CircleGeometry::GetPositionUVBufferCPU(const ContentContext& renderer, auto vertices_per_geom = ComputeCircleDivisions( entity.GetTransformation().GetMaxBasisLength() * radius, round_); - auto points_per_circle = 3 + (vertices_per_geom - 3) * 3; + auto points_per_circle = 2 * vertices_per_geom + 1; auto total = points_per_circle * points_.size(); auto radian_start = round_ ? 0.0f : 0.785398f; auto radian_step = k2Pi / vertices_per_geom; @@ -165,23 +155,11 @@ CircleGeometry::GetPositionUVBufferCPU(const ContentContext& renderer, for (auto i = 0u; i < points_.size(); i++) { auto center = points_[i]; - - auto origin = center + angle_table[0]; - vtx_builder.AppendVertex({origin}); - - auto pt1 = center + angle_table[1]; - vtx_builder.AppendVertex({pt1}); - - auto pt2 = center + angle_table[2]; - vtx_builder.AppendVertex({pt2}); - - for (auto j = 0u; j < vertices_per_geom - 3; j++) { - vtx_builder.AppendVertex({origin}); - vtx_builder.AppendVertex({pt2}); - - pt2 = center + angle_table[j + 3]; - vtx_builder.AppendVertex({pt2}); + for (auto j = 0u; j < vertices_per_geom; j++) { + vtx_builder.AppendVertex({center + angle_table[j]}); + vtx_builder.AppendVertex({center}); } + vtx_builder.AppendVertex({center + angle_table[0]}); } return vtx_builder; } @@ -207,7 +185,7 @@ GeometryResult CircleGeometry::GetPositionBufferGPU( auto vertices_per_geom = ComputeCircleDivisions( entity.GetTransformation().GetMaxBasisLength() * radius, round_); - auto points_per_circle = 3 + (vertices_per_geom - 3) * 3; + auto points_per_circle = 2 * vertices_per_geom + 1; auto total = points_per_circle * points_.size(); auto cmd_buffer = renderer.GetContext()->CreateCommandBuffer(); @@ -292,7 +270,7 @@ GeometryResult CircleGeometry::GetPositionBufferGPU( } return { - .type = PrimitiveType::kTriangle, + .type = PrimitiveType::kTriangleStrip, .vertex_buffer = {.vertex_buffer = output, .vertex_count = total, .index_type = IndexType::kNone}, diff --git a/impeller/entity/shaders/geometry/points.comp b/impeller/entity/shaders/geometry/points.comp index 7d274ade49948..b6a176104c622 100644 --- a/impeller/entity/shaders/geometry/points.comp +++ b/impeller/entity/shaders/geometry/points.comp @@ -38,30 +38,17 @@ void main() { vec2 center = point_data.points[ident]; uint bufer_offset = ident * frame_info.points_per_circle; - float16_t elapsed_angle = frame_info.radian_start; - - vec2 origin = - center + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; - geometry_data.geometry[bufer_offset++] = origin; - - elapsed_angle += frame_info.radian_step; - vec2 pt1 = - center + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; - geometry_data.geometry[bufer_offset++] = pt1; - - elapsed_angle += frame_info.radian_step; - vec2 pt2 = - center + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; - geometry_data.geometry[bufer_offset++] = pt2; - - for (int i = 0; i < frame_info.divisions_per_circle - 3; i++) { - geometry_data.geometry[bufer_offset++] = origin; - geometry_data.geometry[bufer_offset++] = pt2; + for (int i = 0; i < frame_info.divisions_per_circle; i++) { + geometry_data.geometry[bufer_offset++] = + center + + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; + geometry_data.geometry[bufer_offset++] = center; elapsed_angle += frame_info.radian_step; - pt2 = center + - vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; - geometry_data.geometry[bufer_offset++] = pt2; } + geometry_data.geometry[bufer_offset++] = + center + + vec2(cos(frame_info.radian_start), sin(frame_info.radian_start)) * + frame_info.radius; } From 674a1d0609c7fe6fab354a46abe8289f6487602a Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 9 Nov 2023 14:53:16 -0800 Subject: [PATCH 5/9] ++ --- impeller/tools/malioc.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index 1aa9b4e8a8242..ac06206d192c3 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -8163,19 +8163,19 @@ "load_store" ], "total_cycles": [ - 0.296875, - 0.296875, + 0.28125, + 0.234375, 0.28125, 0.1875, - 5.0, + 3.0, 0.0 ] }, "shared_storage_used": 0, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 20, - "work_registers_used": 16 + "uniform_registers_used": 16, + "work_registers_used": 14 } } } From c696eb909af7837d619cb22511db10b9912f54ef Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 9 Nov 2023 15:56:00 -0800 Subject: [PATCH 6/9] ++ --- impeller/entity/geometry/circle_geometry.cc | 2 +- impeller/entity/shaders/geometry/points.comp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/impeller/entity/geometry/circle_geometry.cc b/impeller/entity/geometry/circle_geometry.cc index 99fc17c7770e8..05af9ad421cc8 100644 --- a/impeller/entity/geometry/circle_geometry.cc +++ b/impeller/entity/geometry/circle_geometry.cc @@ -11,7 +11,7 @@ namespace impeller { // The minimum number of points before compute is used to fill out the geometry. // This number was arbitrarily chosen. -static constexpr size_t kMinComputeSize = 32; +static constexpr size_t kMinComputeSize = 4; CircleGeometry::CircleGeometry(std::vector points, Scalar radius, diff --git a/impeller/entity/shaders/geometry/points.comp b/impeller/entity/shaders/geometry/points.comp index b6a176104c622..d4b36229f649d 100644 --- a/impeller/entity/shaders/geometry/points.comp +++ b/impeller/entity/shaders/geometry/points.comp @@ -39,6 +39,7 @@ void main() { vec2 center = point_data.points[ident]; uint bufer_offset = ident * frame_info.points_per_circle; float16_t elapsed_angle = frame_info.radian_start; + for (int i = 0; i < frame_info.divisions_per_circle; i++) { geometry_data.geometry[bufer_offset++] = center + @@ -47,6 +48,7 @@ void main() { elapsed_angle += frame_info.radian_step; } + geometry_data.geometry[bufer_offset++] = center + vec2(cos(frame_info.radian_start), sin(frame_info.radian_start)) * From b57a6da9838677429e877988c2108efdc44b276f Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 9 Nov 2023 20:15:46 -0800 Subject: [PATCH 7/9] Revert "++" This reverts commit c696eb909af7837d619cb22511db10b9912f54ef. --- impeller/entity/geometry/circle_geometry.cc | 2 +- impeller/entity/shaders/geometry/points.comp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/impeller/entity/geometry/circle_geometry.cc b/impeller/entity/geometry/circle_geometry.cc index 05af9ad421cc8..99fc17c7770e8 100644 --- a/impeller/entity/geometry/circle_geometry.cc +++ b/impeller/entity/geometry/circle_geometry.cc @@ -11,7 +11,7 @@ namespace impeller { // The minimum number of points before compute is used to fill out the geometry. // This number was arbitrarily chosen. -static constexpr size_t kMinComputeSize = 4; +static constexpr size_t kMinComputeSize = 32; CircleGeometry::CircleGeometry(std::vector points, Scalar radius, diff --git a/impeller/entity/shaders/geometry/points.comp b/impeller/entity/shaders/geometry/points.comp index d4b36229f649d..b6a176104c622 100644 --- a/impeller/entity/shaders/geometry/points.comp +++ b/impeller/entity/shaders/geometry/points.comp @@ -39,7 +39,6 @@ void main() { vec2 center = point_data.points[ident]; uint bufer_offset = ident * frame_info.points_per_circle; float16_t elapsed_angle = frame_info.radian_start; - for (int i = 0; i < frame_info.divisions_per_circle; i++) { geometry_data.geometry[bufer_offset++] = center + @@ -48,7 +47,6 @@ void main() { elapsed_angle += frame_info.radian_step; } - geometry_data.geometry[bufer_offset++] = center + vec2(cos(frame_info.radian_start), sin(frame_info.radian_start)) * From f4a83ca3f44484045a58b9c4ddf0dab8522aff54 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 9 Nov 2023 20:15:51 -0800 Subject: [PATCH 8/9] Revert "++" This reverts commit 674a1d0609c7fe6fab354a46abe8289f6487602a. --- impeller/tools/malioc.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index ac06206d192c3..1aa9b4e8a8242 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -8163,19 +8163,19 @@ "load_store" ], "total_cycles": [ - 0.28125, - 0.234375, + 0.296875, + 0.296875, 0.28125, 0.1875, - 3.0, + 5.0, 0.0 ] }, "shared_storage_used": 0, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 16, - "work_registers_used": 14 + "uniform_registers_used": 20, + "work_registers_used": 16 } } } From ff999e3fc5196273f49020e05aa796888512968a Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 9 Nov 2023 20:16:01 -0800 Subject: [PATCH 9/9] Revert "++" This reverts commit 4ecec73ef60e83bd5bf9d03c8738233f9088458a. --- impeller/entity/geometry/circle_geometry.cc | 52 ++++++++++++++------ impeller/entity/shaders/geometry/points.comp | 31 ++++++++---- 2 files changed, 59 insertions(+), 24 deletions(-) diff --git a/impeller/entity/geometry/circle_geometry.cc b/impeller/entity/geometry/circle_geometry.cc index 99fc17c7770e8..ac6f603da6ae1 100644 --- a/impeller/entity/geometry/circle_geometry.cc +++ b/impeller/entity/geometry/circle_geometry.cc @@ -29,7 +29,7 @@ GeometryResult CircleGeometry::GetPositionBuffer(const ContentContext& renderer, } return { - .type = PrimitiveType::kTriangleStrip, + .type = PrimitiveType::kTriangle, .vertex_buffer = GetPositionBufferCPU(renderer, entity, pass), .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), @@ -58,7 +58,7 @@ GeometryResult CircleGeometry::GetPositionUVBuffer( auto& host_buffer = pass.GetTransientsBuffer(); return { - .type = PrimitiveType::kTriangleStrip, + .type = PrimitiveType::kTriangle, .vertex_buffer = uv_vtx_builder.CreateVertexBuffer(host_buffer), .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), @@ -83,8 +83,7 @@ VertexBuffer CircleGeometry::GetPositionBufferCPU( auto vertices_per_geom = ComputeCircleDivisions( entity.GetTransformation().GetMaxBasisLength() * radius, round_); - - auto points_per_circle = vertices_per_geom * 2 + 1; + auto points_per_circle = 3 + (vertices_per_geom - 3) * 3; auto total = points_per_circle * points_.size(); auto radian_start = round_ ? 0.0f : 0.785398f; auto radian_step = k2Pi / vertices_per_geom; @@ -105,11 +104,22 @@ VertexBuffer CircleGeometry::GetPositionBufferCPU( auto offset = 0u; for (auto i = 0u; i < points_.size(); i++) { auto center = points_[i]; - for (auto j = 0u; j < vertices_per_geom; j++) { - points[offset++] = center + angle_table[j]; - points[offset++] = center; + + auto origin = center + angle_table[0]; + points[offset++] = origin; + + auto pt1 = center + angle_table[1]; + points[offset++] = pt1; + + auto pt2 = center + angle_table[2]; + points[offset++] = pt2; + + for (auto j = 0u; j < vertices_per_geom - 3; j++) { + points[offset++] = origin; + points[offset++] = pt2; + pt2 = center + angle_table[j + 3]; + points[offset++] = pt2; } - points[offset++] = center + angle_table[0]; } }); @@ -137,7 +147,7 @@ CircleGeometry::GetPositionUVBufferCPU(const ContentContext& renderer, auto vertices_per_geom = ComputeCircleDivisions( entity.GetTransformation().GetMaxBasisLength() * radius, round_); - auto points_per_circle = 2 * vertices_per_geom + 1; + auto points_per_circle = 3 + (vertices_per_geom - 3) * 3; auto total = points_per_circle * points_.size(); auto radian_start = round_ ? 0.0f : 0.785398f; auto radian_step = k2Pi / vertices_per_geom; @@ -155,11 +165,23 @@ CircleGeometry::GetPositionUVBufferCPU(const ContentContext& renderer, for (auto i = 0u; i < points_.size(); i++) { auto center = points_[i]; - for (auto j = 0u; j < vertices_per_geom; j++) { - vtx_builder.AppendVertex({center + angle_table[j]}); - vtx_builder.AppendVertex({center}); + + auto origin = center + angle_table[0]; + vtx_builder.AppendVertex({origin}); + + auto pt1 = center + angle_table[1]; + vtx_builder.AppendVertex({pt1}); + + auto pt2 = center + angle_table[2]; + vtx_builder.AppendVertex({pt2}); + + for (auto j = 0u; j < vertices_per_geom - 3; j++) { + vtx_builder.AppendVertex({origin}); + vtx_builder.AppendVertex({pt2}); + + pt2 = center + angle_table[j + 3]; + vtx_builder.AppendVertex({pt2}); } - vtx_builder.AppendVertex({center + angle_table[0]}); } return vtx_builder; } @@ -185,7 +207,7 @@ GeometryResult CircleGeometry::GetPositionBufferGPU( auto vertices_per_geom = ComputeCircleDivisions( entity.GetTransformation().GetMaxBasisLength() * radius, round_); - auto points_per_circle = 2 * vertices_per_geom + 1; + auto points_per_circle = 3 + (vertices_per_geom - 3) * 3; auto total = points_per_circle * points_.size(); auto cmd_buffer = renderer.GetContext()->CreateCommandBuffer(); @@ -270,7 +292,7 @@ GeometryResult CircleGeometry::GetPositionBufferGPU( } return { - .type = PrimitiveType::kTriangleStrip, + .type = PrimitiveType::kTriangle, .vertex_buffer = {.vertex_buffer = output, .vertex_count = total, .index_type = IndexType::kNone}, diff --git a/impeller/entity/shaders/geometry/points.comp b/impeller/entity/shaders/geometry/points.comp index b6a176104c622..7d274ade49948 100644 --- a/impeller/entity/shaders/geometry/points.comp +++ b/impeller/entity/shaders/geometry/points.comp @@ -38,17 +38,30 @@ void main() { vec2 center = point_data.points[ident]; uint bufer_offset = ident * frame_info.points_per_circle; + float16_t elapsed_angle = frame_info.radian_start; - for (int i = 0; i < frame_info.divisions_per_circle; i++) { - geometry_data.geometry[bufer_offset++] = - center + - vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; - geometry_data.geometry[bufer_offset++] = center; + + vec2 origin = + center + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; + geometry_data.geometry[bufer_offset++] = origin; + + elapsed_angle += frame_info.radian_step; + vec2 pt1 = + center + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; + geometry_data.geometry[bufer_offset++] = pt1; + + elapsed_angle += frame_info.radian_step; + vec2 pt2 = + center + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; + geometry_data.geometry[bufer_offset++] = pt2; + + for (int i = 0; i < frame_info.divisions_per_circle - 3; i++) { + geometry_data.geometry[bufer_offset++] = origin; + geometry_data.geometry[bufer_offset++] = pt2; elapsed_angle += frame_info.radian_step; + pt2 = center + + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; + geometry_data.geometry[bufer_offset++] = pt2; } - geometry_data.geometry[bufer_offset++] = - center + - vec2(cos(frame_info.radian_start), sin(frame_info.radian_start)) * - frame_info.radius; }