From 961008cf1fd44bf8b3726e105a1f7cc4c1d13afd Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sun, 7 May 2023 12:33:32 -0700 Subject: [PATCH 01/40] [Impeller] compute circles in vertex shader --- impeller/aiks/canvas.cc | 13 ++ impeller/aiks/canvas.h | 2 + impeller/display_list/dl_dispatcher.cc | 5 + impeller/display_list/skia_conversions.cc | 8 ++ impeller/display_list/skia_conversions.h | 2 + impeller/entity/BUILD.gn | 1 + impeller/entity/contents/content_context.cc | 19 +++ impeller/entity/contents/content_context.h | 23 +++- impeller/entity/geometry.cc | 118 ++++++++++++++++++ impeller/entity/geometry.h | 36 ++++++ impeller/entity/shaders/geometry/points.vert | 55 ++++++++ .../backend/metal/pipeline_library_mtl.mm | 1 + impeller/renderer/pipeline_builder.h | 46 ++++--- impeller/renderer/pipeline_descriptor.cc | 12 +- impeller/renderer/pipeline_descriptor.h | 5 + 15 files changed, 326 insertions(+), 20 deletions(-) create mode 100644 impeller/entity/shaders/geometry/points.vert diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 662ea009cd6ce..4e4562853bcec 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -373,6 +373,19 @@ void Canvas::RestoreClip() { GetCurrentPass().AddEntity(entity); } +void Canvas::DrawPoints(std::vector points, + Scalar radius, + const Paint& paint) { + Entity entity; + entity.SetTransformation(GetCurrentTransformation()); + entity.SetStencilDepth(GetStencilDepth()); + entity.SetBlendMode(paint.blend_mode); + entity.SetContents(paint.WithFilters(paint.CreateContentsForGeometry( + Geometry::MakePointField(std::move(points), radius)))); + + GetCurrentPass().AddEntity(entity); +} + void Canvas::DrawPicture(Picture picture) { if (!picture.pass) { return; diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index 54be12491b09d..c177ba90cd00e 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -100,6 +100,8 @@ class Canvas { void DrawCircle(Point center, Scalar radius, const Paint& paint); + void DrawPoints(std::vector, Scalar radius, const Paint& paint); + void DrawImage(const std::shared_ptr& image, Point offset, const Paint& paint, diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index 157efbaee69a7..d9134817ecb76 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -918,6 +918,11 @@ void DlDispatcher::drawPoints(PointMode mode, if (paint.stroke_cap == Cap::kButt) { paint.stroke_cap = Cap::kSquare; } + if (paint.stroke_cap == Cap::kRound) { + canvas_.DrawPoints(skia_conversions::ToPoints(points, count), + paint.stroke_width, paint); + break; + } for (uint32_t i = 0; i < count; i++) { Point p0 = skia_conversions::ToPoint(points[i]); auto path = PathBuilder{}.AddLine(p0, p0).TakePath(); diff --git a/impeller/display_list/skia_conversions.cc b/impeller/display_list/skia_conversions.cc index 7b54fef8a552d..572583e0c3830 100644 --- a/impeller/display_list/skia_conversions.cc +++ b/impeller/display_list/skia_conversions.cc @@ -26,6 +26,14 @@ std::vector ToRects(const SkRect tex[], int count) { return result; } +std::vector ToPoints(const SkPoint points[], int count) { + std::vector result(count); + for (auto i = 0; i < count; i++) { + result[i] = ToPoint(points[i]); + } + return result; +} + PathBuilder::RoundingRadii ToRoundingRadii(const SkRRect& rrect) { using Corner = SkRRect::Corner; PathBuilder::RoundingRadii radii; diff --git a/impeller/display_list/skia_conversions.h b/impeller/display_list/skia_conversions.h index 933875bee7101..5f1524674240d 100644 --- a/impeller/display_list/skia_conversions.h +++ b/impeller/display_list/skia_conversions.h @@ -26,6 +26,8 @@ std::optional ToRect(const SkRect* rect); std::vector ToRects(const SkRect tex[], int count); +std::vector ToPoints(const SkPoint points[], int count); + Point ToPoint(const SkPoint& point); Color ToColor(const SkColor& color); diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 91ffdae65d58b..c4135b9df1901 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -97,6 +97,7 @@ impeller_shaders("modern_entity_shaders") { "shaders/linear_gradient_ssbo_fill.frag", "shaders/radial_gradient_ssbo_fill.frag", "shaders/sweep_gradient_ssbo_fill.frag", + "shaders/geometry/points.vert", ] } diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index a8f1e8e54151b..c05774e422bca 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -144,6 +144,7 @@ void ContentContextOptions::ApplyToPipelineDescriptor( desc.SetPrimitiveType(primitive_type); desc.SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill); + desc.SetEnableRasterization(enable_rasterization); } template @@ -161,6 +162,22 @@ static std::unique_ptr CreateDefaultPipeline( return std::make_unique(context, desc); } +template +static std::unique_ptr CreateDefaultNonRenderingPipeline( + const Context& context) { + auto desc = PipelineT::Builder::MakeDefaultPipelineDescriptor(context); + if (!desc.has_value()) { + return nullptr; + } + // Apply default ContentContextOptions to the descriptor. + const auto default_color_fmt = + context.GetCapabilities()->GetDefaultColorFormat(); + ContentContextOptions{.color_attachment_pixel_format = default_color_fmt, + .enable_rasterization = false} + .ApplyToPipelineDescriptor(*desc); + return std::make_unique(context, desc); +} + ContentContext::ContentContext(std::shared_ptr context) : context_(std::move(context)), tessellator_(std::make_shared()), @@ -294,6 +311,8 @@ ContentContext::ContentContext(std::shared_ptr context) CreateDefaultPipeline(*context_); porter_duff_blend_pipelines_[{}] = CreateDefaultPipeline(*context_); + point_field_geometry_pipelines_[{}] = + CreateDefaultNonRenderingPipeline(*context_); if (solid_fill_pipelines_[{}]->GetDescriptor().has_value()) { auto clip_pipeline_descriptor = diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 65941ceda19f4..d0dc2dcc84014 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -40,6 +40,7 @@ #include "impeller/entity/linear_to_srgb_filter.vert.h" #include "impeller/entity/morphology_filter.frag.h" #include "impeller/entity/morphology_filter.vert.h" +#include "impeller/entity/points.vert.h" #include "impeller/entity/porter_duff_blend.frag.h" #include "impeller/entity/radial_gradient_fill.frag.h" #include "impeller/entity/rrect_blur.frag.h" @@ -275,6 +276,9 @@ using FramebufferBlendScreenPipeline = using FramebufferBlendSoftLightPipeline = RenderPipelineT; +/// Geometry Pipelines +using PointFieldGeometryPipeline = + RenderPipelineT; /// Pipeline state configuration. /// @@ -295,13 +299,14 @@ struct ContentContextOptions { std::optional color_attachment_pixel_format; bool has_stencil_attachment = true; bool wireframe = false; + bool enable_rasterization = true; struct Hash { constexpr std::size_t operator()(const ContentContextOptions& o) const { - return fml::HashCombine(o.sample_count, o.blend_mode, o.stencil_compare, - o.stencil_operation, o.primitive_type, - o.color_attachment_pixel_format, - o.has_stencil_attachment, o.wireframe); + return fml::HashCombine( + o.sample_count, o.blend_mode, o.stencil_compare, o.stencil_operation, + o.primitive_type, o.color_attachment_pixel_format, + o.has_stencil_attachment, o.wireframe, o.enable_rasterization); } }; @@ -316,7 +321,8 @@ struct ContentContextOptions { lhs.color_attachment_pixel_format == rhs.color_attachment_pixel_format && lhs.has_stencil_attachment == rhs.has_stencil_attachment && - lhs.wireframe == rhs.wireframe; + lhs.wireframe == rhs.wireframe && + lhs.enable_rasterization == rhs.enable_rasterization; } }; @@ -661,6 +667,11 @@ class ContentContext { return GetPipeline(framebuffer_blend_softlight_pipelines_, opts); } + std::shared_ptr> GetPointFieldGeometryPipeline( + ContentContextOptions opts) const { + return GetPipeline(point_field_geometry_pipelines_, opts); + } + std::shared_ptr GetContext() const; std::shared_ptr GetGlyphAtlasContext() const; @@ -783,6 +794,8 @@ class ContentContext { mutable Variants framebuffer_blend_softlight_pipelines_; + mutable Variants point_field_geometry_pipelines_; + template std::shared_ptr> GetPipeline( Variants& container, diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index 612d9cb3a1af2..d07006ad6e618 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -4,6 +4,7 @@ #include "impeller/entity/geometry.h" +#include #include "impeller/core/device_buffer.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/entity.h" @@ -38,6 +39,13 @@ std::unique_ptr Geometry::MakeRRect(Rect rect, Scalar corner_radius) { return std::make_unique(rect, corner_radius); } +// static +std::unique_ptr Geometry::MakePointField(std::vector points, + Scalar radius) { + return std::make_unique(std::move(points), radius); +} + +// static std::unique_ptr Geometry::MakeStrokePath(const Path& path, Scalar stroke_width, Scalar miter_limit, @@ -883,4 +891,114 @@ std::optional RRectGeometry::GetCoverage(const Matrix& transform) const { return rect_.TransformBounds(transform); } +/////// PointFieldGeometry Geometry /////// + +PointFieldGeometry::PointFieldGeometry(std::vector points, Scalar radius) + : points_(std::move(points)), radius_(radius) {} + +PointFieldGeometry::~PointFieldGeometry() = default; + +GeometryResult PointFieldGeometry::GetPositionBuffer( + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) { + auto divisions_per_circle = ComputeResultSize( + entity.GetTransformation().GetMaxBasisLength() * radius_, points_.size()); + auto total = divisions_per_circle * points_.size() * 3; + auto& host_buffer = pass.GetTransientsBuffer(); + + using VS = PointFieldGeometryPipeline::VertexShader; + VertexBufferBuilder vertex_builder; + for (auto i = 0u; i < points_.size(); i++) { + vertex_builder.AppendVertex( + {.center = points_[i], .offset = static_cast(i)}); + } + + DeviceBufferDescriptor buffer_desc; + buffer_desc.size = total * sizeof(Point); + buffer_desc.storage_mode = StorageMode::kDevicePrivate; + + auto buffer = + renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); + + // Create Dummy index buffer. + auto index_count = divisions_per_circle * points_.size() * 3; + std::vector dummy_index(index_count); + for (auto i = 0u; i < index_count; i++) { + dummy_index[i] = i; + } + auto index_buffer = host_buffer.Emplace( + dummy_index.data(), index_count * sizeof(uint32_t), alignof(uint32_t)); + + Command cmd; + cmd.label = "Points Geometry"; + + auto options = OptionsFromPass(pass); + options.blend_mode = BlendMode::kSource; + options.stencil_compare = CompareFunction::kAlways; + options.stencil_operation = StencilOperation::kKeep; + options.enable_rasterization = false; + cmd.pipeline = renderer.GetPointFieldGeometryPipeline(options); + + VS::FrameInfo frame_info; + frame_info.radius = radius_; + frame_info.radian_step = k2Pi / divisions_per_circle; + frame_info.points_per_circle = divisions_per_circle * 3; + frame_info.divisions_per_circle = divisions_per_circle; + frame_info.total_length = total; + + VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); + VS::BindGeometryData( + cmd, {.buffer = buffer, .range = Range{0, total * sizeof(Point)}}); + + cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); + + if (!pass.AddCommand(std::move(cmd))) { + return {}; + } + + return { + .type = PrimitiveType::kTriangle, + .vertex_buffer = {.vertex_buffer = {.buffer = buffer, + .range = + Range{0, total * sizeof(Point)}}, + + .index_buffer = index_buffer, + .index_count = index_count, + .index_type = IndexType::k32bit}, + .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(), + .prevent_overdraw = false, + }; +} + +GeometryResult PointFieldGeometry::GetPositionUVBuffer( + Rect texture_coverage, + Matrix effect_transform, + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) { + return {}; +} + +/// @brief Compute the exact storage size needed to store the resulting buffer. +/// @return +size_t PointFieldGeometry::ComputeResultSize(Scalar scaled_radius, + size_t point_count) { + // note: this formula is completely arbitrary, we should find a reasonable + // curve based on experimental data. + return 8; +} + +// |Geometry| +GeometryVertexType PointFieldGeometry::GetVertexType() const { + return GeometryVertexType::kPosition; +} + +// |Geometry| +std::optional PointFieldGeometry::GetCoverage( + const Matrix& transform) const { + return Rect::MakeMaximum(); +} + } // namespace impeller diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index bcf9190766a32..7c4a3b786f377 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -54,6 +54,9 @@ class Geometry { static std::unique_ptr MakeRect(Rect rect); + static std::unique_ptr MakePointField(std::vector points, + Scalar radius); + virtual GeometryResult GetPositionBuffer(const ContentContext& renderer, const Entity& entity, RenderPass& pass) = 0; @@ -290,4 +293,37 @@ class RRectGeometry : public Geometry { FML_DISALLOW_COPY_AND_ASSIGN(RRectGeometry); }; +class PointFieldGeometry : public Geometry { + public: + explicit PointFieldGeometry(std::vector points, Scalar radius); + + ~PointFieldGeometry(); + + private: + // |Geometry| + GeometryResult GetPositionBuffer(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) override; + + // |Geometry| + GeometryResult GetPositionUVBuffer(Rect texture_coverage, + Matrix effect_transform, + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) override; + + // |Geometry| + GeometryVertexType GetVertexType() const override; + + // |Geometry| + std::optional GetCoverage(const Matrix& transform) const override; + + static size_t ComputeResultSize(Scalar scaled_radius, size_t point_count); + + std::vector points_; + Scalar radius_; + + FML_DISALLOW_COPY_AND_ASSIGN(PointFieldGeometry); +}; + } // namespace impeller diff --git a/impeller/entity/shaders/geometry/points.vert b/impeller/entity/shaders/geometry/points.vert new file mode 100644 index 0000000000000..330a1a8ff3e10 --- /dev/null +++ b/impeller/entity/shaders/geometry/points.vert @@ -0,0 +1,55 @@ +// 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 +#include + +// TODO(jonahwilliams): with some adjustments to start and end angles, +// this could draw squars and closed arcs too. + +uniform FrameInfo { + float radius; + float16_t radian_step; + int points_per_circle; + int divisions_per_circle; + int total_length; +} +frame_info; + +layout(std430) writeonly buffer GeometryData { + vec2 geometry[]; +} +geometry_data; + +in vec2 center; +in int offset; + +void main() { + // The buffer offset we start writing to is the number of data per circle * + // number of previous circles. + int bufer_offset = offset * frame_info.points_per_circle; + + float16_t elapsed_angle = 0.0hf; + geometry_data.geometry[bufer_offset++] = center; + + vec2 pt1 = center + vec2(1, 0) * 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 = 1; i < frame_info.divisions_per_circle; i++) { + geometry_data.geometry[bufer_offset++] = center; + + pt1 = pt2; + elapsed_angle += frame_info.radian_step; + geometry_data.geometry[bufer_offset++] = pt1; + + pt2 = center + + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; + geometry_data.geometry[bufer_offset++] = pt2; + } +} diff --git a/impeller/renderer/backend/metal/pipeline_library_mtl.mm b/impeller/renderer/backend/metal/pipeline_library_mtl.mm index c65e31f1e7a43..e7b74e55499e2 100644 --- a/impeller/renderer/backend/metal/pipeline_library_mtl.mm +++ b/impeller/renderer/backend/metal/pipeline_library_mtl.mm @@ -27,6 +27,7 @@ auto descriptor = [[MTLRenderPipelineDescriptor alloc] init]; descriptor.label = @(desc.GetLabel().c_str()); descriptor.rasterSampleCount = static_cast(desc.GetSampleCount()); + descriptor.rasterizationEnabled = desc.GetRasterizationEnabled(); for (const auto& entry : desc.GetStageEntrypoints()) { if (entry.first == ShaderStage::kVertex) { diff --git a/impeller/renderer/pipeline_builder.h b/impeller/renderer/pipeline_builder.h index b27c4bc753b55..213375603d3ff 100644 --- a/impeller/renderer/pipeline_builder.h +++ b/impeller/renderer/pipeline_builder.h @@ -16,6 +16,15 @@ namespace impeller { +class NonRenderingFragment { + public: + static constexpr std::string_view kLabel = "NonRendering"; + static constexpr std::string_view kEntrypointName = "non_rendering_main"; + static constexpr ShaderStage kShaderStage = ShaderStage::kFragment; + static constexpr std::string_view kGeneratorName = ""; + static constexpr std::array kDescriptorSetLayouts{}; +}; + //------------------------------------------------------------------------------ /// @brief An optional (but highly recommended) utility for creating /// pipelines from reflected shader information. @@ -52,35 +61,44 @@ struct PipelineBuilder { PipelineDescriptor desc; if (InitializePipelineDescriptorDefaults(context, desc)) { return {std::move(desc)}; - } else { - return std::nullopt; } + return std::nullopt; } [[nodiscard]] static bool InitializePipelineDescriptorDefaults( const Context& context, PipelineDescriptor& desc) { // Setup debug instrumentation. - desc.SetLabel(SPrintF("%s Pipeline", FragmentShader::kLabel.data())); + if (!std::is_same::value) { + desc.SetLabel(SPrintF("%s Pipeline", FragmentShader::kLabel.data())); + } // Resolve pipeline entrypoints. { auto vertex_function = context.GetShaderLibrary()->GetFunction( VertexShader::kEntrypointName, ShaderStage::kVertex); - auto fragment_function = context.GetShaderLibrary()->GetFunction( - FragmentShader::kEntrypointName, ShaderStage::kFragment); - - if (!vertex_function || !fragment_function) { - VALIDATION_LOG << "Could not resolve pipeline entrypoint(s) '" - << VertexShader::kEntrypointName << "' and '" - << FragmentShader::kEntrypointName - << "' for pipeline named '" << VertexShader::kLabel - << "'."; - return false; + + std::shared_ptr fragment_function; + if (!std::is_same::value) { + fragment_function = context.GetShaderLibrary()->GetFunction( + FragmentShader::kEntrypointName, ShaderStage::kFragment); + } + + if (!std::is_same::value) { + if (!vertex_function || !fragment_function) { + VALIDATION_LOG << "Could not resolve pipeline entrypoint(s) '" + << VertexShader::kEntrypointName << "' and '" + << FragmentShader::kEntrypointName + << "' for pipeline named '" << VertexShader::kLabel + << "'."; + return false; + } } desc.AddStageEntrypoint(std::move(vertex_function)); - desc.AddStageEntrypoint(std::move(fragment_function)); + if (fragment_function != nullptr) { + desc.AddStageEntrypoint(std::move(fragment_function)); + } } // Setup the vertex descriptor from reflected information. diff --git a/impeller/renderer/pipeline_descriptor.cc b/impeller/renderer/pipeline_descriptor.cc index eef517b30c847..a0541a60c4168 100644 --- a/impeller/renderer/pipeline_descriptor.cc +++ b/impeller/renderer/pipeline_descriptor.cc @@ -42,6 +42,7 @@ std::size_t PipelineDescriptor::GetHash() const { fml::HashCombineSeed(seed, cull_mode_); fml::HashCombineSeed(seed, primitive_type_); fml::HashCombineSeed(seed, polygon_mode_); + fml::HashCombineSeed(seed, enable_rasterization_); return seed; } @@ -61,7 +62,8 @@ bool PipelineDescriptor::IsEqual(const PipelineDescriptor& other) const { winding_order_ == other.winding_order_ && cull_mode_ == other.cull_mode_ && primitive_type_ == other.primitive_type_ && - polygon_mode_ == other.polygon_mode_; + polygon_mode_ == other.polygon_mode_ && + enable_rasterization_ == other.enable_rasterization_; } PipelineDescriptor& PipelineDescriptor::SetLabel(std::string label) { @@ -235,6 +237,14 @@ PixelFormat PipelineDescriptor::GetDepthPixelFormat() const { return depth_pixel_format_; } +void PipelineDescriptor::SetEnableRasterization(bool value) { + enable_rasterization_ = value; +} + +bool PipelineDescriptor::GetRasterizationEnabled() const { + return enable_rasterization_; +} + std::optional PipelineDescriptor::GetBackStencilAttachmentDescriptor() const { return back_stencil_attachment_descriptor_; diff --git a/impeller/renderer/pipeline_descriptor.h b/impeller/renderer/pipeline_descriptor.h index 3d0eddf880e28..0769c7231a585 100644 --- a/impeller/renderer/pipeline_descriptor.h +++ b/impeller/renderer/pipeline_descriptor.h @@ -131,6 +131,10 @@ class PipelineDescriptor final : public Comparable { PolygonMode GetPolygonMode() const; + void SetEnableRasterization(bool value); + + bool GetRasterizationEnabled() const; + private: std::string label_; SampleCount sample_count_ = SampleCount::kCount1; @@ -149,6 +153,7 @@ class PipelineDescriptor final : public Comparable { back_stencil_attachment_descriptor_; PrimitiveType primitive_type_ = PrimitiveType::kTriangle; PolygonMode polygon_mode_ = PolygonMode::kFill; + bool enable_rasterization_ = true; }; } // namespace impeller From 56638b07705cfd5dc792fa899517bd116f146bf5 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sun, 7 May 2023 17:47:15 -0700 Subject: [PATCH 02/40] ++ --- impeller/entity/geometry.cc | 39 ++++++++++++++------ impeller/entity/shaders/geometry/points.vert | 3 +- impeller/renderer/vertex_buffer_builder.h | 4 +- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index d07006ad6e618..039665a44bfbc 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -908,12 +908,24 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( auto& host_buffer = pass.GetTransientsBuffer(); using VS = PointFieldGeometryPipeline::VertexShader; - VertexBufferBuilder vertex_builder; - for (auto i = 0u; i < points_.size(); i++) { - vertex_builder.AppendVertex( - {.center = points_[i], .offset = static_cast(i)}); + + // Create Dummy index buffer. + auto index_count = divisions_per_circle * points_.size() * 3; + std::vector dummy_index(index_count); + for (auto i = 0u; i < index_count; i++) { + dummy_index[i] = i; } + auto vtx_buffer = VertexBuffer{ + .vertex_buffer = host_buffer.Emplace( + points_.data(), points_.size() * sizeof(Point), alignof(Point)), + .index_buffer = host_buffer.Emplace(dummy_index.data(), + points_.size() * sizeof(uint32_t), + alignof(uint32_t)), + .index_count = points_.size(), + .index_type = IndexType::k32bit, + }; + DeviceBufferDescriptor buffer_desc; buffer_desc.size = total * sizeof(Point); buffer_desc.storage_mode = StorageMode::kDevicePrivate; @@ -921,12 +933,6 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( auto buffer = renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); - // Create Dummy index buffer. - auto index_count = divisions_per_circle * points_.size() * 3; - std::vector dummy_index(index_count); - for (auto i = 0u; i < index_count; i++) { - dummy_index[i] = i; - } auto index_buffer = host_buffer.Emplace( dummy_index.data(), index_count * sizeof(uint32_t), alignof(uint32_t)); @@ -951,7 +957,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( VS::BindGeometryData( cmd, {.buffer = buffer, .range = Range{0, total * sizeof(Point)}}); - cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); + cmd.BindVertices(vtx_buffer); if (!pass.AddCommand(std::move(cmd))) { return {}; @@ -987,7 +993,16 @@ size_t PointFieldGeometry::ComputeResultSize(Scalar scaled_radius, size_t point_count) { // note: this formula is completely arbitrary, we should find a reasonable // curve based on experimental data. - return 8; + if (scaled_radius < 4.0) { + return 8; + } + if (scaled_radius < 16) { + return 16; + } + if (scaled_radius < 32) { + return 32; + } + return 64; } // |Geometry| diff --git a/impeller/entity/shaders/geometry/points.vert b/impeller/entity/shaders/geometry/points.vert index 330a1a8ff3e10..c55be1cedd03a 100644 --- a/impeller/entity/shaders/geometry/points.vert +++ b/impeller/entity/shaders/geometry/points.vert @@ -23,12 +23,11 @@ layout(std430) writeonly buffer GeometryData { geometry_data; in vec2 center; -in int offset; void main() { // The buffer offset we start writing to is the number of data per circle * // number of previous circles. - int bufer_offset = offset * frame_info.points_per_circle; + int bufer_offset = gl_VertexIndex * frame_info.points_per_circle; float16_t elapsed_angle = 0.0hf; geometry_data.geometry[bufer_offset++] = center; diff --git a/impeller/renderer/vertex_buffer_builder.h b/impeller/renderer/vertex_buffer_builder.h index 96c114202f4cf..c49387830f7ad 100644 --- a/impeller/renderer/vertex_buffer_builder.h +++ b/impeller/renderer/vertex_buffer_builder.h @@ -128,9 +128,9 @@ class VertexBufferBuilder { // So dumb! We don't actually need an index buffer right now. But we will // once de-duplication is done. So assume this is always done. - std::vector index_buffer; + std::vector index_buffer(vertices_.size()); for (size_t i = 0; i < vertices_.size(); i++) { - index_buffer.push_back(i); + index_buffer[i] = i; } return index_buffer; } From be1332ad0db7f3eaf11594762124f24b6c9c19d0 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 May 2023 09:40:39 -0700 Subject: [PATCH 03/40] capabilities and license --- ci/licenses_golden/licenses_flutter | 2 ++ impeller/entity/contents/content_context.cc | 8 ++++++-- impeller/entity/contents/content_context.h | 2 ++ impeller/entity/geometry.cc | 6 +++--- impeller/entity/shaders/geometry/points.vert | 1 - impeller/renderer/backend/metal/context_mtl.mm | 1 + impeller/renderer/capabilities.cc | 15 +++++++++++++++ impeller/renderer/capabilities.h | 5 +++++ impeller/renderer/capabilities_unittests.cc | 1 + impeller/renderer/pipeline_builder.h | 2 +- 10 files changed, 36 insertions(+), 7 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index ffcb36dbe7f3f..cfd577956b31b 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1295,6 +1295,7 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_alp ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_alpha_nodecal.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_decal.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_nodecal.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/geometry/points.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.frag + ../../../flutter/LICENSE @@ -3889,6 +3890,7 @@ FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_alpha FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_alpha_nodecal.frag FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_decal.frag FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_nodecal.frag +FILE: ../../../flutter/impeller/entity/shaders/geometry/points.vert FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.frag diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index c05774e422bca..ac9610ad1b9a1 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -311,8 +311,12 @@ ContentContext::ContentContext(std::shared_ptr context) CreateDefaultPipeline(*context_); porter_duff_blend_pipelines_[{}] = CreateDefaultPipeline(*context_); - point_field_geometry_pipelines_[{}] = - CreateDefaultNonRenderingPipeline(*context_); + + if (context_->GetCapabilities()->SupportsDisabledRasterization()) { + point_field_geometry_pipelines_[{}] = + CreateDefaultNonRenderingPipeline( + *context_); + } if (solid_fill_pipelines_[{}]->GetDescriptor().has_value()) { auto clip_pipeline_descriptor = diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index d0dc2dcc84014..4396e271ecd9d 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -276,6 +276,7 @@ using FramebufferBlendScreenPipeline = using FramebufferBlendSoftLightPipeline = RenderPipelineT; + /// Geometry Pipelines using PointFieldGeometryPipeline = RenderPipelineT; @@ -669,6 +670,7 @@ class ContentContext { std::shared_ptr> GetPointFieldGeometryPipeline( ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsDisabledRasterization()); return GetPipeline(point_field_geometry_pipelines_, opts); } diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index 039665a44bfbc..3f475c0f722ff 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -902,6 +902,8 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( const ContentContext& renderer, const Entity& entity, RenderPass& pass) { + FML_DCHECK(renderer.GetDeviceCapabilities().SupportsDisabledRasterization()); + auto divisions_per_circle = ComputeResultSize( entity.GetTransformation().GetMaxBasisLength() * radius_, points_.size()); auto total = divisions_per_circle * points_.size() * 3; @@ -951,7 +953,6 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( frame_info.radian_step = k2Pi / divisions_per_circle; frame_info.points_per_circle = divisions_per_circle * 3; frame_info.divisions_per_circle = divisions_per_circle; - frame_info.total_length = total; VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); VS::BindGeometryData( @@ -968,7 +969,6 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( .vertex_buffer = {.vertex_buffer = {.buffer = buffer, .range = Range{0, total * sizeof(Point)}}, - .index_buffer = index_buffer, .index_count = index_count, .index_type = IndexType::k32bit}, @@ -984,7 +984,7 @@ GeometryResult PointFieldGeometry::GetPositionUVBuffer( const ContentContext& renderer, const Entity& entity, RenderPass& pass) { - return {}; + FML_UNREACHABLE(); } /// @brief Compute the exact storage size needed to store the resulting buffer. diff --git a/impeller/entity/shaders/geometry/points.vert b/impeller/entity/shaders/geometry/points.vert index c55be1cedd03a..65cb764c62786 100644 --- a/impeller/entity/shaders/geometry/points.vert +++ b/impeller/entity/shaders/geometry/points.vert @@ -13,7 +13,6 @@ uniform FrameInfo { float16_t radian_step; int points_per_circle; int divisions_per_circle; - int total_length; } frame_info; diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm index c83f5b7075c47..12862b76f81e3 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -62,6 +62,7 @@ static bool DeviceSupportsComputeSubgroups(id device) { .SetSupportsComputeSubgroups(DeviceSupportsComputeSubgroups(device)) .SetSupportsReadFromResolve(true) .SetSupportsReadFromOnscreenTexture(true) + .SetSupportsDisabledRasterization(true) .Build(); } diff --git a/impeller/renderer/capabilities.cc b/impeller/renderer/capabilities.cc index d0531f5f265b2..bb41c2644261a 100644 --- a/impeller/renderer/capabilities.cc +++ b/impeller/renderer/capabilities.cc @@ -66,6 +66,11 @@ class StandardCapabilities final : public Capabilities { return supports_decal_tile_mode_; } + // |Capabilities| + bool SupportsDisabledRasterization() const override { + return supports_disabled_rasterization_; + } + // |Capabilities| PixelFormat GetDefaultColorFormat() const override { return default_color_format_; @@ -88,6 +93,7 @@ class StandardCapabilities final : public Capabilities { bool supports_read_from_onscreen_texture, bool supports_read_from_resolve, bool supports_decal_tile_mode, + bool supports_disabled_rasterization, PixelFormat default_color_format, PixelFormat default_stencil_format) : has_threading_restrictions_(has_threading_restrictions), @@ -102,6 +108,7 @@ class StandardCapabilities final : public Capabilities { supports_read_from_onscreen_texture), supports_read_from_resolve_(supports_read_from_resolve), supports_decal_tile_mode_(supports_decal_tile_mode), + supports_disabled_rasterization_(supports_disabled_rasterization), default_color_format_(default_color_format), default_stencil_format_(default_stencil_format) {} @@ -118,6 +125,7 @@ class StandardCapabilities final : public Capabilities { bool supports_read_from_onscreen_texture_ = false; bool supports_read_from_resolve_ = false; bool supports_decal_tile_mode_ = false; + bool supports_disabled_rasterization_ = false; PixelFormat default_color_format_ = PixelFormat::kUnknown; PixelFormat default_stencil_format_ = PixelFormat::kUnknown; @@ -202,6 +210,12 @@ CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsDecalTileMode(bool value) { return *this; } +CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsDisabledRasterization( + bool value) { + supports_disabled_rasterization_ = value; + return *this; +} + std::unique_ptr CapabilitiesBuilder::Build() { return std::unique_ptr(new StandardCapabilities( // has_threading_restrictions_, // @@ -215,6 +229,7 @@ std::unique_ptr CapabilitiesBuilder::Build() { supports_read_from_onscreen_texture_, // supports_read_from_resolve_, // supports_decal_tile_mode_, // + supports_disabled_rasterization_, // *default_color_format_, // *default_stencil_format_ // )); diff --git a/impeller/renderer/capabilities.h b/impeller/renderer/capabilities.h index 6fb1118dd7c95..a0ce72baa0f62 100644 --- a/impeller/renderer/capabilities.h +++ b/impeller/renderer/capabilities.h @@ -37,6 +37,8 @@ class Capabilities { virtual bool SupportsDecalTileMode() const = 0; + virtual bool SupportsDisabledRasterization() const = 0; + virtual PixelFormat GetDefaultColorFormat() const = 0; virtual PixelFormat GetDefaultStencilFormat() const = 0; @@ -79,6 +81,8 @@ class CapabilitiesBuilder { CapabilitiesBuilder& SetSupportsDecalTileMode(bool value); + CapabilitiesBuilder& SetSupportsDisabledRasterization(bool value); + std::unique_ptr Build(); private: @@ -93,6 +97,7 @@ class CapabilitiesBuilder { bool supports_read_from_onscreen_texture_ = false; bool supports_read_from_resolve_ = false; bool supports_decal_tile_mode_ = false; + bool supports_disabled_rasterization_ = false; std::optional default_color_format_ = std::nullopt; std::optional default_stencil_format_ = std::nullopt; diff --git a/impeller/renderer/capabilities_unittests.cc b/impeller/renderer/capabilities_unittests.cc index 1dc9d17e3c678..1b95a01481e1f 100644 --- a/impeller/renderer/capabilities_unittests.cc +++ b/impeller/renderer/capabilities_unittests.cc @@ -29,6 +29,7 @@ CAPABILITY_TEST(SupportsComputeSubgroups, false); CAPABILITY_TEST(SupportsReadFromOnscreenTexture, false); CAPABILITY_TEST(SupportsReadFromResolve, false); CAPABILITY_TEST(SupportsDecalTileMode, false); +CAPABILITY_TEST(SupportsDisabledRasterization, false); } // namespace testing } // namespace impeller diff --git a/impeller/renderer/pipeline_builder.h b/impeller/renderer/pipeline_builder.h index 213375603d3ff..caf8115690904 100644 --- a/impeller/renderer/pipeline_builder.h +++ b/impeller/renderer/pipeline_builder.h @@ -21,7 +21,7 @@ class NonRenderingFragment { static constexpr std::string_view kLabel = "NonRendering"; static constexpr std::string_view kEntrypointName = "non_rendering_main"; static constexpr ShaderStage kShaderStage = ShaderStage::kFragment; - static constexpr std::string_view kGeneratorName = ""; + static constexpr std::string_view kGeneratorName = "NonRendering"; static constexpr std::array kDescriptorSetLayouts{}; }; From 7a83b0dd9f81df803140bf7e17292ab921c99135 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 May 2023 10:34:43 -0700 Subject: [PATCH 04/40] add support for square caps --- impeller/aiks/canvas.cc | 5 +++-- impeller/aiks/canvas.h | 8 ++++++- impeller/display_list/dl_dispatcher.cc | 22 ++++++------------- impeller/entity/geometry.cc | 23 +++++++++++++------- impeller/entity/geometry.h | 8 ++++--- impeller/entity/shaders/geometry/points.vert | 6 +++-- 6 files changed, 41 insertions(+), 31 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 4e4562853bcec..9e07a1c6f0c0a 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -375,13 +375,14 @@ void Canvas::RestoreClip() { void Canvas::DrawPoints(std::vector points, Scalar radius, - const Paint& paint) { + const Paint& paint, + PointStyle point_style) { Entity entity; entity.SetTransformation(GetCurrentTransformation()); entity.SetStencilDepth(GetStencilDepth()); entity.SetBlendMode(paint.blend_mode); entity.SetContents(paint.WithFilters(paint.CreateContentsForGeometry( - Geometry::MakePointField(std::move(points), radius)))); + Geometry::MakePointField(std::move(points), radius, /*round=*/point_style == PointStyle::kRound)))); GetCurrentPass().AddEntity(entity); } diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index c177ba90cd00e..8143726c68a80 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -37,6 +37,12 @@ struct CanvasStackEntry { bool contains_clips = false; }; +enum PointStyle { + kRound, + + kSquare, +}; + class Canvas { public: struct DebugOptions { @@ -100,7 +106,7 @@ class Canvas { void DrawCircle(Point center, Scalar radius, const Paint& paint); - void DrawPoints(std::vector, Scalar radius, const Paint& paint); + void DrawPoints(std::vector, Scalar radius, const Paint& paint, PointStyle point_style); void DrawImage(const std::shared_ptr& image, Point offset, diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index d9134817ecb76..56865b047f919 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -914,21 +914,13 @@ void DlDispatcher::drawPoints(PointMode mode, Paint paint = paint_; paint.style = Paint::Style::kStroke; switch (mode) { - case flutter::DlCanvas::PointMode::kPoints: - if (paint.stroke_cap == Cap::kButt) { - paint.stroke_cap = Cap::kSquare; - } - if (paint.stroke_cap == Cap::kRound) { - canvas_.DrawPoints(skia_conversions::ToPoints(points, count), - paint.stroke_width, paint); - break; - } - for (uint32_t i = 0; i < count; i++) { - Point p0 = skia_conversions::ToPoint(points[i]); - auto path = PathBuilder{}.AddLine(p0, p0).TakePath(); - canvas_.DrawPath(path, paint); - } - break; + case flutter::DlCanvas::PointMode::kPoints: { + // Cap::kButt is also treated as a square. + auto point_style = paint.stroke_cap == Cap::kRound ? PointStyle::kRound + : PointStyle::kSquare; + canvas_.DrawPoints(skia_conversions::ToPoints(points, count), + paint.stroke_width, paint, point_style); + } break; case flutter::DlCanvas::PointMode::kLines: for (uint32_t i = 1; i < count; i += 2) { Point p0 = skia_conversions::ToPoint(points[i - 1]); diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index 3f475c0f722ff..dd0b8a24f5c69 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -41,8 +41,9 @@ std::unique_ptr Geometry::MakeRRect(Rect rect, Scalar corner_radius) { // static std::unique_ptr Geometry::MakePointField(std::vector points, - Scalar radius) { - return std::make_unique(std::move(points), radius); + Scalar radius, + bool round) { + return std::make_unique(std::move(points), radius, round); } // static @@ -893,8 +894,10 @@ std::optional RRectGeometry::GetCoverage(const Matrix& transform) const { /////// PointFieldGeometry Geometry /////// -PointFieldGeometry::PointFieldGeometry(std::vector points, Scalar radius) - : points_(std::move(points)), radius_(radius) {} +PointFieldGeometry::PointFieldGeometry(std::vector points, + Scalar radius, + bool round) + : points_(std::move(points)), radius_(radius), round_(round) {} PointFieldGeometry::~PointFieldGeometry() = default; @@ -904,8 +907,8 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( RenderPass& pass) { FML_DCHECK(renderer.GetDeviceCapabilities().SupportsDisabledRasterization()); - auto divisions_per_circle = ComputeResultSize( - entity.GetTransformation().GetMaxBasisLength() * radius_, points_.size()); + auto divisions_per_circle = ComputeCircleDivisions( + entity.GetTransformation().GetMaxBasisLength() * radius_, round_); auto total = divisions_per_circle * points_.size() * 3; auto& host_buffer = pass.GetTransientsBuffer(); @@ -950,6 +953,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( VS::FrameInfo frame_info; frame_info.radius = radius_; + frame_info.radian_start = round_ ? 0 : 0.785398; frame_info.radian_step = k2Pi / divisions_per_circle; frame_info.points_per_circle = divisions_per_circle * 3; frame_info.divisions_per_circle = divisions_per_circle; @@ -989,8 +993,11 @@ GeometryResult PointFieldGeometry::GetPositionUVBuffer( /// @brief Compute the exact storage size needed to store the resulting buffer. /// @return -size_t PointFieldGeometry::ComputeResultSize(Scalar scaled_radius, - size_t point_count) { +size_t PointFieldGeometry::ComputeCircleDivisions(Scalar scaled_radius, + bool round) { + if (!round) { + return 4; + } // note: this formula is completely arbitrary, we should find a reasonable // curve based on experimental data. if (scaled_radius < 4.0) { diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index 7c4a3b786f377..bc296c438a3e9 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -55,7 +55,8 @@ class Geometry { static std::unique_ptr MakeRect(Rect rect); static std::unique_ptr MakePointField(std::vector points, - Scalar radius); + Scalar radius, + bool round); virtual GeometryResult GetPositionBuffer(const ContentContext& renderer, const Entity& entity, @@ -295,7 +296,7 @@ class RRectGeometry : public Geometry { class PointFieldGeometry : public Geometry { public: - explicit PointFieldGeometry(std::vector points, Scalar radius); + PointFieldGeometry(std::vector points, Scalar radius, bool round); ~PointFieldGeometry(); @@ -318,10 +319,11 @@ class PointFieldGeometry : public Geometry { // |Geometry| std::optional GetCoverage(const Matrix& transform) const override; - static size_t ComputeResultSize(Scalar scaled_radius, size_t point_count); + static size_t ComputeCircleDivisions(Scalar scaled_radius, bool round); std::vector points_; Scalar radius_; + bool round_; FML_DISALLOW_COPY_AND_ASSIGN(PointFieldGeometry); }; diff --git a/impeller/entity/shaders/geometry/points.vert b/impeller/entity/shaders/geometry/points.vert index 65cb764c62786..ed5f1c2e50011 100644 --- a/impeller/entity/shaders/geometry/points.vert +++ b/impeller/entity/shaders/geometry/points.vert @@ -10,6 +10,7 @@ uniform FrameInfo { float radius; + float16_t radian_start; float16_t radian_step; int points_per_circle; int divisions_per_circle; @@ -28,10 +29,11 @@ void main() { // number of previous circles. int bufer_offset = gl_VertexIndex * frame_info.points_per_circle; - float16_t elapsed_angle = 0.0hf; + float16_t elapsed_angle = frame_info.radian_start; geometry_data.geometry[bufer_offset++] = center; - vec2 pt1 = center + vec2(1, 0) * frame_info.radius; + 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; From d36a4527c44957f3f6f493843dbeb1cbb04e6ce4 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 May 2023 10:46:46 -0700 Subject: [PATCH 05/40] ++ --- impeller/aiks/canvas.cc | 3 ++- impeller/aiks/canvas.h | 5 ++++- impeller/entity/shaders/geometry/points.vert | 7 ++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 9e07a1c6f0c0a..6a4726a39caf7 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -382,7 +382,8 @@ void Canvas::DrawPoints(std::vector points, entity.SetStencilDepth(GetStencilDepth()); entity.SetBlendMode(paint.blend_mode); entity.SetContents(paint.WithFilters(paint.CreateContentsForGeometry( - Geometry::MakePointField(std::move(points), radius, /*round=*/point_style == PointStyle::kRound)))); + Geometry::MakePointField(std::move(points), radius, + /*round=*/point_style == PointStyle::kRound)))); GetCurrentPass().AddEntity(entity); } diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index 8143726c68a80..e5ebc8cb317f4 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -106,7 +106,10 @@ class Canvas { void DrawCircle(Point center, Scalar radius, const Paint& paint); - void DrawPoints(std::vector, Scalar radius, const Paint& paint, PointStyle point_style); + void DrawPoints(std::vector, + Scalar radius, + const Paint& paint, + PointStyle point_style); void DrawImage(const std::shared_ptr& image, Point offset, diff --git a/impeller/entity/shaders/geometry/points.vert b/impeller/entity/shaders/geometry/points.vert index ed5f1c2e50011..3828392ec03a7 100644 --- a/impeller/entity/shaders/geometry/points.vert +++ b/impeller/entity/shaders/geometry/points.vert @@ -5,11 +5,8 @@ #include #include -// TODO(jonahwilliams): with some adjustments to start and end angles, -// this could draw squars and closed arcs too. - uniform FrameInfo { - float radius; + float16_t radius; float16_t radian_start; float16_t radian_step; int points_per_circle; @@ -22,7 +19,7 @@ layout(std430) writeonly buffer GeometryData { } geometry_data; -in vec2 center; +in f16vec2 center; void main() { // The buffer offset we start writing to is the number of data per circle * From 69ea8a985d8b79136ce1c9ad54bfd8d2141fdf1e Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 May 2023 11:56:26 -0700 Subject: [PATCH 06/40] ++ --- impeller/renderer/backend/vulkan/capabilities_vk.cc | 4 ++++ impeller/renderer/backend/vulkan/capabilities_vk.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/impeller/renderer/backend/vulkan/capabilities_vk.cc b/impeller/renderer/backend/vulkan/capabilities_vk.cc index ff4410f15935a..1416ed07e0436 100644 --- a/impeller/renderer/backend/vulkan/capabilities_vk.cc +++ b/impeller/renderer/backend/vulkan/capabilities_vk.cc @@ -352,6 +352,10 @@ bool CapabilitiesVK::SupportsDecalTileMode() const { return true; } +bool CapabilitiesVK::SupportsDisabledRasterization() const { + return true; +} + // |Capabilities| PixelFormat CapabilitiesVK::GetDefaultColorFormat() const { return color_format_; diff --git a/impeller/renderer/backend/vulkan/capabilities_vk.h b/impeller/renderer/backend/vulkan/capabilities_vk.h index 006ed6f0e0889..90d01b445bd9f 100644 --- a/impeller/renderer/backend/vulkan/capabilities_vk.h +++ b/impeller/renderer/backend/vulkan/capabilities_vk.h @@ -79,6 +79,9 @@ class CapabilitiesVK final : public Capabilities, // |Capabilities| bool SupportsDecalTileMode() const override; + // |Capabilities| + bool SupportsDisabledRasterization() const override; + // |Capabilities| PixelFormat GetDefaultColorFormat() const override; From 6a830a7711999f57065d12e375334eeade3dc706 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 May 2023 15:07:53 -0700 Subject: [PATCH 07/40] ++ --- impeller/tools/malioc.json | 61 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index e9e21d268c9d4..f3fe83a8b7f54 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -12327,6 +12327,67 @@ } } }, + "flutter/impeller/entity/points.vert.vkspv": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/points.vert.vkspv", + "has_uniform_computation": true, + "type": "Vertex", + "variants": { + "Position": { + "fp16_arithmetic": 30, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + null + ], + "longest_path_cycles": [ + null, + null, + null, + null, + null, + null + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "load_store" + ], + "shortest_path_cycles": [ + 0.203125, + 0.03125, + 0.203125, + 0.0625, + 3.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 0.375, + 0.203125, + 0.375, + 0.1875, + 5.0, + 0.0 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 12, + "work_registers_used": 17 + } + } + } + }, "flutter/impeller/entity/porter_duff_blend.frag.vkspv": { "Mali-G78": { "core": "Mali-G78", From 5cec1a4bd919c92725ef18a81858d1cd5d10ceca Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 May 2023 15:09:13 -0700 Subject: [PATCH 08/40] switch to enum class and add docs --- impeller/aiks/canvas.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index e5ebc8cb317f4..5833317c0072b 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -37,9 +37,11 @@ struct CanvasStackEntry { bool contains_clips = false; }; -enum PointStyle { +enum class PointStyle { + /// @brief Points are drawn as squares. kRound, + /// @brief Points are drawn as circles. kSquare, }; From de05b5c232367f45b90b74b6aaf2a6b1ae1126d8 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 8 May 2023 19:35:33 -0700 Subject: [PATCH 09/40] fix offsets --- impeller/entity/shaders/geometry/points.vert | 2 +- impeller/renderer/pipeline_builder.h | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/impeller/entity/shaders/geometry/points.vert b/impeller/entity/shaders/geometry/points.vert index 3828392ec03a7..5e3a748b6e353 100644 --- a/impeller/entity/shaders/geometry/points.vert +++ b/impeller/entity/shaders/geometry/points.vert @@ -19,7 +19,7 @@ layout(std430) writeonly buffer GeometryData { } geometry_data; -in f16vec2 center; +in vec2 center; void main() { // The buffer offset we start writing to is the number of data per circle * diff --git a/impeller/renderer/pipeline_builder.h b/impeller/renderer/pipeline_builder.h index caf8115690904..a567f43c23093 100644 --- a/impeller/renderer/pipeline_builder.h +++ b/impeller/renderer/pipeline_builder.h @@ -18,10 +18,10 @@ namespace impeller { class NonRenderingFragment { public: - static constexpr std::string_view kLabel = "NonRendering"; - static constexpr std::string_view kEntrypointName = "non_rendering_main"; + static constexpr std::string_view kLabel = ""; + static constexpr std::string_view kEntrypointName = ""; static constexpr ShaderStage kShaderStage = ShaderStage::kFragment; - static constexpr std::string_view kGeneratorName = "NonRendering"; + static constexpr std::string_view kGeneratorName = ""; static constexpr std::array kDescriptorSetLayouts{}; }; @@ -71,6 +71,8 @@ struct PipelineBuilder { // Setup debug instrumentation. if (!std::is_same::value) { desc.SetLabel(SPrintF("%s Pipeline", FragmentShader::kLabel.data())); + } else { + desc.SetLabel(SPrintF("%s Pipeline", VertexShader::kLabel.data())); } // Resolve pipeline entrypoints. @@ -93,6 +95,14 @@ struct PipelineBuilder { << "'."; return false; } + } else { + if (!vertex_function) { + VALIDATION_LOG << "Could not resolve pipeline entrypoint(s) '" + << FragmentShader::kEntrypointName + << "' for pipeline named '" << VertexShader::kLabel + << "'."; + return false; + } } desc.AddStageEntrypoint(std::move(vertex_function)); From f0a82973898c8d7e19fd34f5d472d933c8096c33 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 10 May 2023 09:48:43 -0700 Subject: [PATCH 10/40] use different render pass --- impeller/entity/geometry.cc | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index c4693e970c25a..30afa0f11ece8 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -4,7 +4,6 @@ #include "impeller/entity/geometry.h" -#include #include "impeller/core/device_buffer.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/entity.h" @@ -12,6 +11,7 @@ #include "impeller/entity/texture_fill.vert.h" #include "impeller/geometry/matrix.h" #include "impeller/geometry/path_builder.h" +#include "impeller/renderer/command_buffer.h" #include "impeller/renderer/render_pass.h" #include "impeller/tessellator/tessellator.h" @@ -969,7 +969,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( // Create Dummy index buffer. auto index_count = divisions_per_circle * points_.size() * 3; - std::vector dummy_index(index_count); + std::vector dummy_index(index_count); for (auto i = 0u; i < index_count; i++) { dummy_index[i] = i; } @@ -978,10 +978,10 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( .vertex_buffer = host_buffer.Emplace( points_.data(), points_.size() * sizeof(Point), alignof(Point)), .index_buffer = host_buffer.Emplace(dummy_index.data(), - points_.size() * sizeof(uint32_t), - alignof(uint32_t)), + points_.size() * sizeof(uint16_t), + alignof(uint16_t)), .index_count = points_.size(), - .index_type = IndexType::k32bit, + .index_type = IndexType::k16bit, }; DeviceBufferDescriptor buffer_desc; @@ -992,7 +992,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); auto index_buffer = host_buffer.Emplace( - dummy_index.data(), index_count * sizeof(uint32_t), alignof(uint32_t)); + dummy_index.data(), index_count * sizeof(uint16_t), alignof(uint16_t)); Command cmd; cmd.label = "Points Geometry"; @@ -1006,7 +1006,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( VS::FrameInfo frame_info; frame_info.radius = radius_; - frame_info.radian_start = round_ ? 0 : 0.785398; + frame_info.radian_start = round_ ? 0.0f : 0.785398f; frame_info.radian_step = k2Pi / divisions_per_circle; frame_info.points_per_circle = divisions_per_circle * 3; frame_info.divisions_per_circle = divisions_per_circle; @@ -1017,8 +1017,18 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( cmd.BindVertices(vtx_buffer); - if (!pass.AddCommand(std::move(cmd))) { - return {}; + // Ensure correct synchronization by submitting vertex computation into + // a different render pass. + { + auto render_target = pass.GetRenderTarget(); + auto cmd_buffer = renderer.GetContext()->CreateCommandBuffer(); + auto vertex_render_pass = cmd_buffer->CreateRenderPass(render_target); + + if (!vertex_render_pass->AddCommand(std::move(cmd)) || + !vertex_render_pass->EncodeCommands() || + !vertex_render_pass->SubmitCommands()) { + return {}; + } } return { @@ -1028,7 +1038,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( Range{0, total * sizeof(Point)}}, .index_buffer = index_buffer, .index_count = index_count, - .index_type = IndexType::k32bit}, + .index_type = IndexType::k16bit}, .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), .prevent_overdraw = false, @@ -1044,7 +1054,8 @@ GeometryResult PointFieldGeometry::GetPositionUVBuffer( FML_UNREACHABLE(); } -/// @brief Compute the exact storage size needed to store the resulting buffer. +/// @brief Compute the exact storage size needed to store the resulting +/// buffer. /// @return size_t PointFieldGeometry::ComputeCircleDivisions(Scalar scaled_radius, bool round) { From faba06fb3eda11bbad079269dab8f757cac49e30 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 10 May 2023 10:26:39 -0700 Subject: [PATCH 11/40] fix merge --- impeller/entity/geometry.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index b727e59be1a6c..5511fd079f7fa 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -893,7 +893,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( if (!vertex_render_pass->AddCommand(std::move(cmd)) || !vertex_render_pass->EncodeCommands() || - !vertex_render_pass->SubmitCommands()) { + !cmd_buffer->SubmitCommands()) { return {}; } } From a8e410674fff5cd68d18bfccc790338971299438 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 10 May 2023 12:09:18 -0700 Subject: [PATCH 12/40] add CPU fallback --- impeller/entity/geometry.cc | 52 ++++++++++++++++++++++++++++++++++++- impeller/entity/geometry.h | 4 +++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index 5511fd079f7fa..e7abbcb19dac4 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -825,7 +825,9 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( const ContentContext& renderer, const Entity& entity, RenderPass& pass) { - FML_DCHECK(renderer.GetDeviceCapabilities().SupportsDisabledRasterization()); + if (!renderer.GetDeviceCapabilities().SupportsDisabledRasterization()) { + return GetPositionBufferCPU(renderer, entity, pass); + } auto divisions_per_circle = ComputeCircleDivisions( entity.GetTransformation().GetMaxBasisLength() * radius_, round_); @@ -912,6 +914,54 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( }; } +GeometryResult PointFieldGeometry::GetPositionBufferCPU( + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) { + auto divisions_per_circle = ComputeCircleDivisions( + entity.GetTransformation().GetMaxBasisLength() * radius_, round_); + auto total = divisions_per_circle * points_.size() * 3; + auto& host_buffer = pass.GetTransientsBuffer(); + auto radian_start = round_ ? 0.0f : 0.785398f; + auto radian_step = k2Pi / divisions_per_circle; + + VertexBufferBuilder vtx_builder; + vtx_builder.Reserve(total); + vtx_builder.ReserveIndices(total); + for (auto i = 0u; i < points_.size(); i++) { + auto elapsed_angle = radian_start; + auto center = points_[i]; + vtx_builder.AppendVertex({center}); + + auto pt1 = center + Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; + vtx_builder.AppendVertex({pt1}); + + elapsed_angle += radian_step; + auto pt2 = center + Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; + vtx_builder.AppendVertex({pt2}); + + for (auto j = 0u; j < divisions_per_circle; j++) { + vtx_builder.AppendVertex({center}); + + pt1 = pt2; + elapsed_angle += radian_step; + vtx_builder.AppendVertex({pt1}); + + pt2 = center + + Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; + vtx_builder.AppendVertex({pt2}); + } + } + + return { + .type = PrimitiveType::kTriangle, + .vertex_buffer = vtx_builder.CreateVertexBuffer(host_buffer), + .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(), + .prevent_overdraw = false, + }; +} + GeometryResult PointFieldGeometry::GetPositionUVBuffer( Rect texture_coverage, Matrix effect_transform, diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index ae42174454c33..6937d173e7bc2 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -291,6 +291,10 @@ class PointFieldGeometry : public Geometry { static size_t ComputeCircleDivisions(Scalar scaled_radius, bool round); + GeometryResult GetPositionBufferCPU(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass); + std::vector points_; Scalar radius_; bool round_; From 8b8f4f813bffe184e1acb740fd3c3a5cf26ebc2f Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 10 May 2023 12:10:28 -0700 Subject: [PATCH 13/40] ++ --- impeller/entity/geometry.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index e7abbcb19dac4..c76e920392017 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -947,8 +947,7 @@ GeometryResult PointFieldGeometry::GetPositionBufferCPU( elapsed_angle += radian_step; vtx_builder.AppendVertex({pt1}); - pt2 = center + - Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; + pt2 = center + Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; vtx_builder.AppendVertex({pt2}); } } From b23b6163243cd51ff6e71233188d03126657c6c4 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 10 May 2023 12:25:16 -0700 Subject: [PATCH 14/40] fix off by one --- impeller/entity/geometry.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index c76e920392017..ffdd79fe8fb2b 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -927,7 +927,7 @@ GeometryResult PointFieldGeometry::GetPositionBufferCPU( VertexBufferBuilder vtx_builder; vtx_builder.Reserve(total); - vtx_builder.ReserveIndices(total); + for (auto i = 0u; i < points_.size(); i++) { auto elapsed_angle = radian_start; auto center = points_[i]; @@ -940,7 +940,7 @@ GeometryResult PointFieldGeometry::GetPositionBufferCPU( auto pt2 = center + Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; vtx_builder.AppendVertex({pt2}); - for (auto j = 0u; j < divisions_per_circle; j++) { + for (auto j = 1u; j < divisions_per_circle; j++) { vtx_builder.AppendVertex({center}); pt1 = pt2; From 0591bf1cf2b18327f07cad884578ac11ac7a1d62 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 11 May 2023 14:52:03 -0700 Subject: [PATCH 15/40] non working index buffer removal --- impeller/core/formats.h | 2 + impeller/core/vertex_buffer.h | 2 +- impeller/display_list/dl_dispatcher.cc | 2 +- impeller/entity/geometry.cc | 56 +++++++++---------- .../renderer/backend/metal/render_pass_mtl.mm | 13 ++++- impeller/renderer/render_pass.cc | 22 ++++---- 6 files changed, 53 insertions(+), 44 deletions(-) diff --git a/impeller/core/formats.h b/impeller/core/formats.h index 7fc4a6f221eb6..820983bbab653 100644 --- a/impeller/core/formats.h +++ b/impeller/core/formats.h @@ -308,6 +308,8 @@ enum class IndexType { kUnknown, k16bit, k32bit, + // Do not use the index buffer. + kNone, }; enum class PrimitiveType { diff --git a/impeller/core/vertex_buffer.h b/impeller/core/vertex_buffer.h index 4e8850f752803..accb0f73e0f6c 100644 --- a/impeller/core/vertex_buffer.h +++ b/impeller/core/vertex_buffer.h @@ -16,7 +16,7 @@ struct VertexBuffer { IndexType index_type = IndexType::kUnknown; constexpr operator bool() const { - return static_cast(vertex_buffer) && static_cast(index_buffer); + return static_cast(vertex_buffer); // && static_cast(index_buffer); } }; diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index 72373d797fb07..fdb8ffd2bab24 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -935,7 +935,7 @@ void DlDispatcher::drawPoints(PointMode mode, auto point_style = paint.stroke_cap == Cap::kRound ? PointStyle::kRound : PointStyle::kSquare; canvas_.DrawPoints(skia_conversions::ToPoints(points, count), - paint.stroke_width, paint, point_style); + paint.stroke_width / 2.0, paint, point_style); } break; case flutter::DlCanvas::PointMode::kLines: for (uint32_t i = 1; i < count; i += 2) { diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index ffdd79fe8fb2b..30c0668a626f9 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "impeller/entity/geometry.h" +#include #include "impeller/core/device_buffer.h" #include "impeller/entity/contents/content_context.h" @@ -825,6 +826,10 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( const ContentContext& renderer, const Entity& entity, RenderPass& pass) { + if (radius_ <= 0) { + return {}; + } + if (!renderer.GetDeviceCapabilities().SupportsDisabledRasterization()) { return GetPositionBufferCPU(renderer, entity, pass); } @@ -836,21 +841,11 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( using VS = PointFieldGeometryPipeline::VertexShader; - // Create Dummy index buffer. - auto index_count = divisions_per_circle * points_.size() * 3; - std::vector dummy_index(index_count); - for (auto i = 0u; i < index_count; i++) { - dummy_index[i] = i; - } - auto vtx_buffer = VertexBuffer{ .vertex_buffer = host_buffer.Emplace( points_.data(), points_.size() * sizeof(Point), alignof(Point)), - .index_buffer = host_buffer.Emplace(dummy_index.data(), - points_.size() * sizeof(uint16_t), - alignof(uint16_t)), .index_count = points_.size(), - .index_type = IndexType::k16bit, + .index_type = IndexType::kNone, }; DeviceBufferDescriptor buffer_desc; @@ -860,9 +855,6 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( auto buffer = renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); - auto index_buffer = host_buffer.Emplace( - dummy_index.data(), index_count * sizeof(uint16_t), alignof(uint16_t)); - Command cmd; cmd.label = "Points Geometry"; @@ -905,9 +897,8 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( .vertex_buffer = {.vertex_buffer = {.buffer = buffer, .range = Range{0, total * sizeof(Point)}}, - .index_buffer = index_buffer, - .index_count = index_count, - .index_type = IndexType::k16bit}, + .index_count = divisions_per_circle * points_.size() * 3, + .index_type = IndexType::kNone}, .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), .prevent_overdraw = false, @@ -925,7 +916,8 @@ GeometryResult PointFieldGeometry::GetPositionBufferCPU( auto radian_start = round_ ? 0.0f : 0.785398f; auto radian_step = k2Pi / divisions_per_circle; - VertexBufferBuilder vtx_builder; + VertexBufferBuilder + vtx_builder; vtx_builder.Reserve(total); for (auto i = 0u; i < points_.size(); i++) { @@ -940,7 +932,7 @@ GeometryResult PointFieldGeometry::GetPositionBufferCPU( auto pt2 = center + Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; vtx_builder.AppendVertex({pt2}); - for (auto j = 1u; j < divisions_per_circle; j++) { + for (auto j = 0u; j < divisions_per_circle - 1; j++) { vtx_builder.AppendVertex({center}); pt1 = pt2; @@ -978,18 +970,22 @@ size_t PointFieldGeometry::ComputeCircleDivisions(Scalar scaled_radius, if (!round) { return 4; } - // note: this formula is completely arbitrary, we should find a reasonable - // curve based on experimental data. - if (scaled_radius < 4.0) { + + // Note: these values are approximated based on the values returned from + // the decomposition of 4 cubics performed by Path::CreatePolyline. + if (scaled_radius < 1.0) { + return 4; + } + if (scaled_radius < 2.0) { return 8; } - if (scaled_radius < 16) { - return 16; + if (scaled_radius < 12.0) { + return 24; } - if (scaled_radius < 32) { - return 32; + if (scaled_radius < 22.0) { + return 34; } - return 64; + return std::min(scaled_radius, 140.0f); } // |Geometry| @@ -1000,7 +996,11 @@ GeometryVertexType PointFieldGeometry::GetVertexType() const { // |Geometry| std::optional PointFieldGeometry::GetCoverage( const Matrix& transform) const { - return Rect::MakeMaximum(); + auto pt_bounds = Rect::MakePointBounds(points_.begin(), points_.end()); + if (pt_bounds.has_value()) { + return pt_bounds->TransformBounds(transform); + } + return std::nullopt; } } // namespace impeller diff --git a/impeller/renderer/backend/metal/render_pass_mtl.mm b/impeller/renderer/backend/metal/render_pass_mtl.mm index 4c912e9772935..3cd982ed6b8ca 100644 --- a/impeller/renderer/backend/metal/render_pass_mtl.mm +++ b/impeller/renderer/backend/metal/render_pass_mtl.mm @@ -3,7 +3,7 @@ // found in the LICENSE file. #include "impeller/renderer/backend/metal/render_pass_mtl.h" - +#include #include "flutter/fml/closure.h" #include "flutter/fml/logging.h" #include "flutter/fml/trace_event.h" @@ -486,6 +486,15 @@ static bool Bind(PassBindingsCache& pass, ShaderStage::kFragment)) { return false; } + const PrimitiveType primitive_type = pipeline_desc.GetPrimitiveType(); + + if (command.index_type == IndexType::kNone) { + [encoder drawPrimitives:ToMTLPrimitiveType(primitive_type) + vertexStart:command.base_vertex + vertexCount:command.index_count]; + return true; + } + if (command.index_type == IndexType::kUnknown) { return false; } @@ -503,8 +512,6 @@ static bool Bind(PassBindingsCache& pass, return false; } - const PrimitiveType primitive_type = pipeline_desc.GetPrimitiveType(); - FML_DCHECK(command.index_count * (command.index_type == IndexType::k16bit ? 2 : 4) == command.index_buffer.range.length); diff --git a/impeller/renderer/render_pass.cc b/impeller/renderer/render_pass.cc index d4e0bde02908a..f46855f1daad9 100644 --- a/impeller/renderer/render_pass.cc +++ b/impeller/renderer/render_pass.cc @@ -49,17 +49,17 @@ bool RenderPass::AddCommand(Command command) { } } - if (command.index_count == 0u) { - // Essentially a no-op. Don't record the command but this is not necessary - // an error either. - return true; - } - - if (command.instance_count == 0u) { - // Essentially a no-op. Don't record the command but this is not necessary - // an error either. - return true; - } + // if (command.index_count == 0u) { + // // Essentially a no-op. Don't record the command but this is not necessary + // // an error either. + // return true; + // } + + // if (command.instance_count == 0u) { + // // Essentially a no-op. Don't record the command but this is not necessary + // // an error either. + // return true; + // } commands_.emplace_back(std::move(command)); return true; From 0fc1ee2e1babf999a3432cb3d5c2a6516824d534 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 11 May 2023 20:48:46 -0700 Subject: [PATCH 16/40] fix no index --- impeller/core/vertex_buffer.h | 3 ++- impeller/entity/geometry.cc | 2 +- .../renderer/backend/metal/render_pass_mtl.mm | 3 ++- impeller/renderer/render_pass.cc | 22 +++++++++---------- impeller/renderer/vertex_buffer_builder.h | 11 +++++++--- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/impeller/core/vertex_buffer.h b/impeller/core/vertex_buffer.h index accb0f73e0f6c..bd5d0724d44fb 100644 --- a/impeller/core/vertex_buffer.h +++ b/impeller/core/vertex_buffer.h @@ -16,7 +16,8 @@ struct VertexBuffer { IndexType index_type = IndexType::kUnknown; constexpr operator bool() const { - return static_cast(vertex_buffer); // && static_cast(index_buffer); + return static_cast(vertex_buffer) && + (index_type == IndexType::kNone || static_cast(index_buffer)); } }; diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index 30c0668a626f9..9bac96a8a11af 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -897,7 +897,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( .vertex_buffer = {.vertex_buffer = {.buffer = buffer, .range = Range{0, total * sizeof(Point)}}, - .index_count = divisions_per_circle * points_.size() * 3, + .index_count = total, .index_type = IndexType::kNone}, .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), diff --git a/impeller/renderer/backend/metal/render_pass_mtl.mm b/impeller/renderer/backend/metal/render_pass_mtl.mm index 3cd982ed6b8ca..76ef6b51afeda 100644 --- a/impeller/renderer/backend/metal/render_pass_mtl.mm +++ b/impeller/renderer/backend/metal/render_pass_mtl.mm @@ -489,10 +489,11 @@ static bool Bind(PassBindingsCache& pass, const PrimitiveType primitive_type = pipeline_desc.GetPrimitiveType(); if (command.index_type == IndexType::kNone) { + auto vtx_buffer = command.GetVertexBuffer(); [encoder drawPrimitives:ToMTLPrimitiveType(primitive_type) vertexStart:command.base_vertex vertexCount:command.index_count]; - return true; + continue; } if (command.index_type == IndexType::kUnknown) { diff --git a/impeller/renderer/render_pass.cc b/impeller/renderer/render_pass.cc index f46855f1daad9..d4e0bde02908a 100644 --- a/impeller/renderer/render_pass.cc +++ b/impeller/renderer/render_pass.cc @@ -49,17 +49,17 @@ bool RenderPass::AddCommand(Command command) { } } - // if (command.index_count == 0u) { - // // Essentially a no-op. Don't record the command but this is not necessary - // // an error either. - // return true; - // } - - // if (command.instance_count == 0u) { - // // Essentially a no-op. Don't record the command but this is not necessary - // // an error either. - // return true; - // } + if (command.index_count == 0u) { + // Essentially a no-op. Don't record the command but this is not necessary + // an error either. + return true; + } + + if (command.instance_count == 0u) { + // Essentially a no-op. Don't record the command but this is not necessary + // an error either. + return true; + } commands_.emplace_back(std::move(command)); return true; diff --git a/impeller/renderer/vertex_buffer_builder.h b/impeller/renderer/vertex_buffer_builder.h index c49387830f7ad..35d1b5d773c25 100644 --- a/impeller/renderer/vertex_buffer_builder.h +++ b/impeller/renderer/vertex_buffer_builder.h @@ -75,9 +75,14 @@ class VertexBufferBuilder { VertexBuffer CreateVertexBuffer(HostBuffer& host_buffer) const { VertexBuffer buffer; buffer.vertex_buffer = CreateVertexBufferView(host_buffer); - buffer.index_buffer = CreateIndexBufferView(host_buffer); - buffer.index_count = GetIndexCount(); - buffer.index_type = GetIndexType(); + if (indices_.size() == 0) { + buffer.index_count = GetVertexCount(); + buffer.index_type = impeller::IndexType::kNone; + } else { + buffer.index_buffer = CreateIndexBufferView(host_buffer); + buffer.index_count = GetIndexCount(); + buffer.index_type = GetIndexType(); + } return buffer; }; From 6d979a2c4be85c8c786e917215e3d680f0e19694 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 11 May 2023 20:49:08 -0700 Subject: [PATCH 17/40] ++ --- impeller/renderer/backend/metal/render_pass_mtl.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/renderer/backend/metal/render_pass_mtl.mm b/impeller/renderer/backend/metal/render_pass_mtl.mm index 76ef6b51afeda..7fb64a7e1bea0 100644 --- a/impeller/renderer/backend/metal/render_pass_mtl.mm +++ b/impeller/renderer/backend/metal/render_pass_mtl.mm @@ -491,8 +491,8 @@ static bool Bind(PassBindingsCache& pass, if (command.index_type == IndexType::kNone) { auto vtx_buffer = command.GetVertexBuffer(); [encoder drawPrimitives:ToMTLPrimitiveType(primitive_type) - vertexStart:command.base_vertex - vertexCount:command.index_count]; + vertexStart:command.base_vertex + vertexCount:command.index_count]; continue; } From a2f218d4d565f6f2c1bd406e8b74c390ab834458 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 11 May 2023 22:16:49 -0700 Subject: [PATCH 18/40] ++ --- impeller/renderer/vertex_buffer_builder.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/impeller/renderer/vertex_buffer_builder.h b/impeller/renderer/vertex_buffer_builder.h index e482882f58dd4..a84bb39d8b35f 100644 --- a/impeller/renderer/vertex_buffer_builder.h +++ b/impeller/renderer/vertex_buffer_builder.h @@ -75,20 +75,9 @@ class VertexBufferBuilder { VertexBuffer CreateVertexBuffer(HostBuffer& host_buffer) const { VertexBuffer buffer; buffer.vertex_buffer = CreateVertexBufferView(host_buffer); -<<<<<<< HEAD - if (indices_.size() == 0) { - buffer.index_count = GetVertexCount(); - buffer.index_type = impeller::IndexType::kNone; - } else { - buffer.index_buffer = CreateIndexBufferView(host_buffer); - buffer.index_count = GetIndexCount(); - buffer.index_type = GetIndexType(); - } -======= buffer.index_buffer = CreateIndexBufferView(host_buffer); buffer.vertex_count = GetIndexCount(); buffer.index_type = GetIndexType(); ->>>>>>> 3e608274c9526b7707c8f3798d41f6e937e386f7 return buffer; }; From cbb0aa64d5d13c16f42b1f13bfd6df1aff16ca57 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 12 May 2023 09:02:16 -0700 Subject: [PATCH 19/40] Rename field --- impeller/entity/geometry.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index 9278bbe71cea2..d4110168f0124 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -838,7 +838,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( auto vtx_buffer = VertexBuffer{ .vertex_buffer = host_buffer.Emplace( points_.data(), points_.size() * sizeof(Point), alignof(Point)), - .index_count = points_.size(), + .vertex_count = points_.size(), .index_type = IndexType::kNone, }; @@ -891,7 +891,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( .vertex_buffer = {.vertex_buffer = {.buffer = buffer, .range = Range{0, total * sizeof(Point)}}, - .index_count = total, + .vertex_count = total, .index_type = IndexType::kNone}, .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), From 87997950c7f05186f76620db80ad0b4a62e8eec9 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 12 May 2023 11:01:44 -0700 Subject: [PATCH 20/40] improve efficiency --- impeller/base/validation.cc | 2 +- impeller/entity/geometry.cc | 42 ++++++++++++-------- impeller/entity/shaders/geometry/points.vert | 14 ++++--- impeller/renderer/render_target.h | 10 ++--- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/impeller/base/validation.cc b/impeller/base/validation.cc index d3a7031622fef..b58e42875c9bd 100644 --- a/impeller/base/validation.cc +++ b/impeller/base/validation.cc @@ -11,7 +11,7 @@ namespace impeller { static std::atomic_int32_t sValidationLogsDisabledCount = 0; -static bool sValidationLogsAreFatal = false; +static bool sValidationLogsAreFatal = true; void ImpellerValidationErrorsSetFatal(bool fatal) { sValidationLogsAreFatal = fatal; diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index 55f3fc870942b..eb8b0630603b0 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -830,7 +830,8 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( auto divisions_per_circle = ComputeCircleDivisions( entity.GetTransformation().GetMaxBasisLength() * radius_, round_); - auto total = divisions_per_circle * points_.size() * 3; + auto points_per_circle = (divisions_per_circle - 2) * 3; + auto total = points_per_circle * points_.size(); auto& host_buffer = pass.GetTransientsBuffer(); using VS = PointFieldGeometryPipeline::VertexShader; @@ -857,13 +858,14 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( options.stencil_compare = CompareFunction::kAlways; options.stencil_operation = StencilOperation::kKeep; options.enable_rasterization = false; + options.sample_count = SampleCount::kCount1; cmd.pipeline = renderer.GetPointFieldGeometryPipeline(options); VS::FrameInfo frame_info; frame_info.radius = radius_; frame_info.radian_start = round_ ? 0.0f : 0.785398f; frame_info.radian_step = k2Pi / divisions_per_circle; - frame_info.points_per_circle = divisions_per_circle * 3; + frame_info.points_per_circle = points_per_circle; frame_info.divisions_per_circle = divisions_per_circle; VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); @@ -912,35 +914,41 @@ GeometryResult PointFieldGeometry::GetPositionBufferCPU( RenderPass& pass) { auto divisions_per_circle = ComputeCircleDivisions( entity.GetTransformation().GetMaxBasisLength() * radius_, round_); - auto total = divisions_per_circle * points_.size() * 3; + auto points_per_circle = (divisions_per_circle - 2) * 3; + auto total = points_per_circle * points_.size(); auto& host_buffer = pass.GetTransientsBuffer(); auto radian_start = round_ ? 0.0f : 0.785398f; auto radian_step = k2Pi / divisions_per_circle; - VertexBufferBuilder - vtx_builder; + VertexBufferBuilder vtx_builder; vtx_builder.Reserve(total); + /// Precompute all relative points and angles for a fixed geometry size. + auto elapsed_angle = radian_start; + std::vector angle_table(divisions_per_circle + 1); + for (auto i = 0u; i < divisions_per_circle + 1; i++) { + angle_table[i] = Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; + elapsed_angle += radian_step; + } + for (auto i = 0u; i < points_.size(); i++) { - auto elapsed_angle = radian_start; auto center = points_[i]; - vtx_builder.AppendVertex({center}); + auto j = 0u; + + auto origin = center + angle_table[j++]; + vtx_builder.AppendVertex({origin}); - auto pt1 = center + Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; + auto pt1 = center + angle_table[j++]; vtx_builder.AppendVertex({pt1}); - elapsed_angle += radian_step; - auto pt2 = center + Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; + auto pt2 = center + angle_table[j++]; vtx_builder.AppendVertex({pt2}); - for (auto j = 0u; j < divisions_per_circle - 1; j++) { - vtx_builder.AppendVertex({center}); - - pt1 = pt2; - elapsed_angle += radian_step; - vtx_builder.AppendVertex({pt1}); + for (auto j = 0u; j < divisions_per_circle - 2; j++) { + vtx_builder.AppendVertex({origin}); + vtx_builder.AppendVertex({pt2}); - pt2 = center + Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; + pt2 = center + angle_table[j++]; vtx_builder.AppendVertex({pt2}); } } diff --git a/impeller/entity/shaders/geometry/points.vert b/impeller/entity/shaders/geometry/points.vert index 5e3a748b6e353..9e4ba05f9a13c 100644 --- a/impeller/entity/shaders/geometry/points.vert +++ b/impeller/entity/shaders/geometry/points.vert @@ -27,8 +27,12 @@ void main() { int bufer_offset = gl_VertexIndex * frame_info.points_per_circle; float16_t elapsed_angle = frame_info.radian_start; - 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; @@ -38,13 +42,11 @@ void main() { center + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; geometry_data.geometry[bufer_offset++] = pt2; - for (int i = 1; i < frame_info.divisions_per_circle; i++) { - geometry_data.geometry[bufer_offset++] = center; + for (int i = 0; i < frame_info.divisions_per_circle - 2; i++) { + geometry_data.geometry[bufer_offset++] = origin; + geometry_data.geometry[bufer_offset++] = pt2; - pt1 = pt2; elapsed_angle += frame_info.radian_step; - geometry_data.geometry[bufer_offset++] = pt1; - pt2 = center + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; geometry_data.geometry[bufer_offset++] = pt2; diff --git a/impeller/renderer/render_target.h b/impeller/renderer/render_target.h index 4bd783c5c626c..2b44a3c9445e0 100644 --- a/impeller/renderer/render_target.h +++ b/impeller/renderer/render_target.h @@ -53,11 +53,11 @@ class RenderTarget final { .store_action = StoreAction::kDontCare, .clear_color = Color::BlackTransparent()}; - static constexpr AttachmentConfig kDefaultColorAttachmentConfigNonRendering = { - .storage_mode = StorageMode::kDevicePrivate, - .load_action = LoadAction::kDontCare, - .store_action = StoreAction::kDontCare, - .clear_color = Color::BlackTransparent()}; + static constexpr AttachmentConfig kDefaultColorAttachmentConfigNonRendering = + {.storage_mode = StorageMode::kDevicePrivate, + .load_action = LoadAction::kDontCare, + .store_action = StoreAction::kDontCare, + .clear_color = Color::BlackTransparent()}; static RenderTarget CreateOffscreen( const Context& context, From b715d4099132bd7ae6374bedf3b9046d0addc137 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 12 May 2023 12:04:18 -0700 Subject: [PATCH 21/40] ++ --- impeller/aiks/canvas.cc | 3 ++ impeller/display_list/dl_dispatcher.cc | 8 ++- impeller/entity/geometry.cc | 51 +++++++++++--------- impeller/entity/geometry.h | 3 +- impeller/entity/shaders/geometry/points.vert | 2 +- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 0b04493d7a43a..c13520f74e4d3 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -387,6 +387,9 @@ void Canvas::DrawPoints(std::vector points, Scalar radius, const Paint& paint, PointStyle point_style) { + if (radius <= 0) { + return; + } Entity entity; entity.SetTransformation(GetCurrentTransformation()); entity.SetStencilDepth(GetStencilDepth()); diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index fdb8ffd2bab24..8adaa55c1e2b8 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -934,8 +934,12 @@ void DlDispatcher::drawPoints(PointMode mode, // Cap::kButt is also treated as a square. auto point_style = paint.stroke_cap == Cap::kRound ? PointStyle::kRound : PointStyle::kSquare; - canvas_.DrawPoints(skia_conversions::ToPoints(points, count), - paint.stroke_width / 2.0, paint, point_style); + auto radius = paint.stroke_width; + if (radius > 0) { + radius /= 2.0; + } + canvas_.DrawPoints(skia_conversions::ToPoints(points, count), radius, + paint, point_style); } break; case flutter::DlCanvas::PointMode::kLines: for (uint32_t i = 1; i < count; i += 2) { diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index eb8b0630603b0..d5516d5fea972 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -820,17 +820,24 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( const ContentContext& renderer, const Entity& entity, RenderPass& pass) { - if (radius_ <= 0) { + 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); + if (!renderer.GetDeviceCapabilities().SupportsDisabledRasterization()) { - return GetPositionBufferCPU(renderer, entity, pass); + return GetPositionBufferCPU(renderer, entity, pass, radius); } - auto divisions_per_circle = ComputeCircleDivisions( - entity.GetTransformation().GetMaxBasisLength() * radius_, round_); - auto points_per_circle = (divisions_per_circle - 2) * 3; + 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& host_buffer = pass.GetTransientsBuffer(); @@ -862,11 +869,11 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( cmd.pipeline = renderer.GetPointFieldGeometryPipeline(options); VS::FrameInfo frame_info; - frame_info.radius = radius_; + frame_info.radius = radius; frame_info.radian_start = round_ ? 0.0f : 0.785398f; - frame_info.radian_step = k2Pi / divisions_per_circle; + frame_info.radian_step = k2Pi / vertices_per_geom; frame_info.points_per_circle = points_per_circle; - frame_info.divisions_per_circle = divisions_per_circle; + frame_info.divisions_per_circle = vertices_per_geom; VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); VS::BindGeometryData( @@ -911,44 +918,44 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( GeometryResult PointFieldGeometry::GetPositionBufferCPU( const ContentContext& renderer, const Entity& entity, - RenderPass& pass) { - auto divisions_per_circle = ComputeCircleDivisions( - entity.GetTransformation().GetMaxBasisLength() * radius_, round_); - auto points_per_circle = (divisions_per_circle - 2) * 3; + RenderPass& pass, + Scalar radius) { + 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& host_buffer = pass.GetTransientsBuffer(); auto radian_start = round_ ? 0.0f : 0.785398f; - auto radian_step = k2Pi / divisions_per_circle; + auto radian_step = k2Pi / vertices_per_geom; VertexBufferBuilder vtx_builder; vtx_builder.Reserve(total); /// Precompute all relative points and angles for a fixed geometry size. auto elapsed_angle = radian_start; - std::vector angle_table(divisions_per_circle + 1); - for (auto i = 0u; i < divisions_per_circle + 1; i++) { - angle_table[i] = Point(cos(elapsed_angle), sin(elapsed_angle)) * radius_; + 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; } for (auto i = 0u; i < points_.size(); i++) { auto center = points_[i]; - auto j = 0u; - auto origin = center + angle_table[j++]; + auto origin = center + angle_table[0]; vtx_builder.AppendVertex({origin}); - auto pt1 = center + angle_table[j++]; + auto pt1 = center + angle_table[1]; vtx_builder.AppendVertex({pt1}); - auto pt2 = center + angle_table[j++]; + auto pt2 = center + angle_table[2]; vtx_builder.AppendVertex({pt2}); - for (auto j = 0u; j < divisions_per_circle - 2; j++) { + for (auto j = 0u; j < vertices_per_geom - 3; j++) { vtx_builder.AppendVertex({origin}); vtx_builder.AppendVertex({pt2}); - pt2 = center + angle_table[j++]; + pt2 = center + angle_table[j + 3]; vtx_builder.AppendVertex({pt2}); } } diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index 6937d173e7bc2..cac8007a6ba58 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -293,7 +293,8 @@ class PointFieldGeometry : public Geometry { GeometryResult GetPositionBufferCPU(const ContentContext& renderer, const Entity& entity, - RenderPass& pass); + RenderPass& pass, + Scalar radius); std::vector points_; Scalar radius_; diff --git a/impeller/entity/shaders/geometry/points.vert b/impeller/entity/shaders/geometry/points.vert index 9e4ba05f9a13c..6e8910cb917c9 100644 --- a/impeller/entity/shaders/geometry/points.vert +++ b/impeller/entity/shaders/geometry/points.vert @@ -42,7 +42,7 @@ void main() { 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 - 2; i++) { + for (int i = 0; i < frame_info.divisions_per_circle - 3; i++) { geometry_data.geometry[bufer_offset++] = origin; geometry_data.geometry[bufer_offset++] = pt2; From 769392586cb428afd22944b961548f41d4852cff Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 12 May 2023 15:55:45 -0700 Subject: [PATCH 22/40] disable on desktop --- impeller/renderer/backend/metal/context_mtl.mm | 13 ++++++++++++- impeller/renderer/backend/vulkan/render_pass_vk.cc | 1 - 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm index 12862b76f81e3..e37757e44195d 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -45,6 +45,17 @@ static bool DeviceSupportsComputeSubgroups(id device) { return supports_subgroups; } +static bool SupportsDisabledRasterization() { + // TOOD(jonahwilliams): on macOS playgrounds there seems to be some alignment + // issues with the device buffers but I haven't been able to trigger any sort + // of validation warnings. Disabling there for now. +#if FML_OS_IOS + return true; +#else + return false; +#endif // FML_OS_IOS +} + static std::unique_ptr InferMetalCapabilities( id device, PixelFormat color_format) { @@ -62,7 +73,7 @@ static bool DeviceSupportsComputeSubgroups(id device) { .SetSupportsComputeSubgroups(DeviceSupportsComputeSubgroups(device)) .SetSupportsReadFromResolve(true) .SetSupportsReadFromOnscreenTexture(true) - .SetSupportsDisabledRasterization(true) + .SetSupportsDisabledRasterization(SupportsDisabledRasterization()) .Build(); } diff --git a/impeller/renderer/backend/vulkan/render_pass_vk.cc b/impeller/renderer/backend/vulkan/render_pass_vk.cc index 87a201eae43df..40c8da7fe8420 100644 --- a/impeller/renderer/backend/vulkan/render_pass_vk.cc +++ b/impeller/renderer/backend/vulkan/render_pass_vk.cc @@ -522,7 +522,6 @@ static bool EncodeCommand(const Context& context, 0u // first instance ); } else { - FML_LOG(ERROR) << "HERE!!!"; cmd_buffer.draw(command.vertex_count, // vertex count command.instance_count, // instance count command.base_vertex, // vertex offset From 6f46186f5eedd71a7737f5c8c9a5a4b4b4025778 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 12 May 2023 19:14:27 -0700 Subject: [PATCH 23/40] fix geometry computation bug --- impeller/aiks/canvas.cc | 1 + impeller/entity/geometry.cc | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index c13520f74e4d3..6ac4df2f0d4fe 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -390,6 +390,7 @@ void Canvas::DrawPoints(std::vector points, if (radius <= 0) { return; } + Entity entity; entity.SetTransformation(GetCurrentTransformation()); entity.SetStencilDepth(GetStencilDepth()); diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index d5516d5fea972..e24b324f6bf44 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "impeller/entity/geometry.h" -#include #include "impeller/core/device_buffer.h" #include "impeller/entity/contents/content_context.h" @@ -1012,9 +1011,23 @@ GeometryVertexType PointFieldGeometry::GetVertexType() const { // |Geometry| std::optional PointFieldGeometry::GetCoverage( const Matrix& transform) const { - auto pt_bounds = Rect::MakePointBounds(points_.begin(), points_.end()); - if (pt_bounds.has_value()) { - return pt_bounds->TransformBounds(transform); + if (points_.size() > 0) { + // Doesn't use MakePointBounds as this isn't resilient to points that + // lie along the same axis. + auto first = points_.begin(); + auto last = points_.end(); + auto left = first->x; + auto top = first->y; + auto right = first->x; + auto bottom = first->y; + for (auto it = first + 1; it < last; ++it) { + left = std::min(left, it->x); + top = std::min(top, it->y); + right = std::max(right, it->x); + bottom = std::max(bottom, it->y); + } + return Rect::MakeLTRB(left - radius_, top - radius_, right + radius_, + bottom + radius_); } return std::nullopt; } From cca59fee692ec40679274c634695f0342dac273c Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 12 May 2023 19:45:38 -0700 Subject: [PATCH 24/40] malioc update --- impeller/tools/malioc.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index c542644d07ae8..2361bcb96c997 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -12075,7 +12075,7 @@ "type": "Vertex", "variants": { "Position": { - "fp16_arithmetic": 30, + "fp16_arithmetic": 35, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ @@ -12102,7 +12102,7 @@ ], "shortest_path_cycles": [ 0.203125, - 0.03125, + 0.046875, 0.203125, 0.0625, 3.0, @@ -12113,7 +12113,7 @@ ], "total_cycles": [ 0.375, - 0.203125, + 0.21875, 0.375, 0.1875, 5.0, @@ -12122,7 +12122,7 @@ }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 12, + "uniform_registers_used": 14, "work_registers_used": 17 } } From f08fff2fff23b1421fe7ffad6c331bb8c1226b59 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 12 May 2023 19:50:11 -0700 Subject: [PATCH 25/40] ++ --- impeller/base/validation.cc | 2 +- impeller/renderer/backend/metal/render_pass_mtl.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/base/validation.cc b/impeller/base/validation.cc index b58e42875c9bd..d3a7031622fef 100644 --- a/impeller/base/validation.cc +++ b/impeller/base/validation.cc @@ -11,7 +11,7 @@ namespace impeller { static std::atomic_int32_t sValidationLogsDisabledCount = 0; -static bool sValidationLogsAreFatal = true; +static bool sValidationLogsAreFatal = false; void ImpellerValidationErrorsSetFatal(bool fatal) { sValidationLogsAreFatal = fatal; diff --git a/impeller/renderer/backend/metal/render_pass_mtl.mm b/impeller/renderer/backend/metal/render_pass_mtl.mm index 003212e33e5e2..1eb63299b23fb 100644 --- a/impeller/renderer/backend/metal/render_pass_mtl.mm +++ b/impeller/renderer/backend/metal/render_pass_mtl.mm @@ -3,7 +3,7 @@ // found in the LICENSE file. #include "impeller/renderer/backend/metal/render_pass_mtl.h" -#include + #include "flutter/fml/closure.h" #include "flutter/fml/logging.h" #include "flutter/fml/trace_event.h" From 36b9ee3e3e242d51a3c23b775fa838f2e72d0bbe Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sat, 13 May 2023 15:43:44 -0700 Subject: [PATCH 26/40] [Impeller] draw cirlces with compute --- impeller/base/validation.cc | 2 +- impeller/entity/BUILD.gn | 1 + impeller/entity/contents/content_context.cc | 7 ++ impeller/entity/contents/content_context.h | 10 +++ impeller/entity/geometry.cc | 87 ++++++++++++-------- impeller/entity/shaders/geometry/points.comp | 67 +++++++++++++++ 6 files changed, 137 insertions(+), 37 deletions(-) create mode 100644 impeller/entity/shaders/geometry/points.comp diff --git a/impeller/base/validation.cc b/impeller/base/validation.cc index d3a7031622fef..b58e42875c9bd 100644 --- a/impeller/base/validation.cc +++ b/impeller/base/validation.cc @@ -11,7 +11,7 @@ namespace impeller { static std::atomic_int32_t sValidationLogsDisabledCount = 0; -static bool sValidationLogsAreFatal = false; +static bool sValidationLogsAreFatal = true; void ImpellerValidationErrorsSetFatal(bool fatal) { sValidationLogsAreFatal = fatal; diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 9a32be2f05872..caaca9926cd45 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -97,6 +97,7 @@ impeller_shaders("modern_entity_shaders") { "shaders/radial_gradient_ssbo_fill.frag", "shaders/sweep_gradient_ssbo_fill.frag", "shaders/geometry/points.vert", + "shaders/geometry/points.comp", ] } diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 70e7b16ac6e23..8da85ca76e20a 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -14,6 +14,7 @@ #include "impeller/renderer/render_pass.h" #include "impeller/renderer/render_target.h" #include "impeller/tessellator/tessellator.h" +#include "impeller/renderer/pipeline_library.h" namespace impeller { @@ -318,6 +319,12 @@ ContentContext::ContentContext(std::shared_ptr context) CreateDefaultNonRenderingPipeline( *context_); } + if (context_->GetCapabilities()->SupportsCompute()) { + auto pipeline_desc = + PointsComputeShaderPipeline::MakeDefaultPipelineDescriptor(*context_); + point_field_compute_pipelines_ = + context_->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get(); + } if (solid_fill_pipelines_[{}]->GetDescriptor().has_value()) { auto clip_pipeline_descriptor = diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 25f2dc36c66ae..6c9f69a1733a2 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -39,6 +39,7 @@ #include "impeller/entity/linear_to_srgb_filter.vert.h" #include "impeller/entity/morphology_filter.frag.h" #include "impeller/entity/morphology_filter.vert.h" +#include "impeller/entity/points.comp.h" #include "impeller/entity/points.vert.h" #include "impeller/entity/porter_duff_blend.frag.h" #include "impeller/entity/radial_gradient_fill.frag.h" @@ -279,6 +280,7 @@ using FramebufferBlendSoftLightPipeline = /// Geometry Pipelines using PointFieldGeometryPipeline = RenderPipelineT; +using PointsComputeShaderPipeline = ComputePipelineBuilder; /// Pipeline state configuration. /// @@ -673,6 +675,12 @@ class ContentContext { return GetPipeline(point_field_geometry_pipelines_, opts); } + std::shared_ptr> GetPointComputePipeline() + const { + FML_DCHECK(GetDeviceCapabilities().SupportsCompute()); + return point_field_compute_pipelines_; + } + std::shared_ptr GetContext() const; std::shared_ptr GetGlyphAtlasContext( @@ -795,6 +803,8 @@ class ContentContext { framebuffer_blend_screen_pipelines_; mutable Variants framebuffer_blend_softlight_pipelines_; + mutable std::shared_ptr> + point_field_compute_pipelines_; mutable Variants point_field_geometry_pipelines_; diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index e24b324f6bf44..fc6ca0069b0d5 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -7,6 +7,7 @@ #include "impeller/core/device_buffer.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/entity.h" +#include "impeller/entity/points.comp.h" #include "impeller/entity/position_color.vert.h" #include "impeller/entity/texture_fill.vert.h" #include "impeller/geometry/matrix.h" @@ -840,14 +841,12 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( auto total = points_per_circle * points_.size(); auto& host_buffer = pass.GetTransientsBuffer(); - using VS = PointFieldGeometryPipeline::VertexShader; + using PS = PointsComputeShader; - auto vtx_buffer = VertexBuffer{ - .vertex_buffer = host_buffer.Emplace( - points_.data(), points_.size() * sizeof(Point), alignof(Point)), - .vertex_count = points_.size(), - .index_type = IndexType::kNone, - }; + // using VS = PointFieldGeometryPipeline::VertexShader; + + auto points_data = host_buffer.Emplace( + points_.data(), points_.size() * sizeof(Point), alignof(Point)); DeviceBufferDescriptor buffer_desc; buffer_desc.size = total * sizeof(Point); @@ -856,51 +855,67 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( auto buffer = renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); - Command cmd; + ComputeCommand cmd; cmd.label = "Points Geometry"; - - auto options = OptionsFromPass(pass); - options.blend_mode = BlendMode::kSource; - options.stencil_compare = CompareFunction::kAlways; - options.stencil_operation = StencilOperation::kKeep; - options.enable_rasterization = false; - options.sample_count = SampleCount::kCount1; - cmd.pipeline = renderer.GetPointFieldGeometryPipeline(options); - - VS::FrameInfo frame_info; + cmd.pipeline = renderer.GetPointComputePipeline(); + + // auto options = OptionsFromPass(pass); + // options.blend_mode = BlendMode::kSource; + // options.stencil_compare = CompareFunction::kAlways; + // options.stencil_operation = StencilOperation::kKeep; + // options.enable_rasterization = false; + // options.sample_count = SampleCount::kCount1; + // cmd.pipeline = renderer.GetPointFieldGeometryPipeline(options); + + PS::FrameInfo frame_info; + frame_info.count = points_.size(); frame_info.radius = radius; frame_info.radian_start = round_ ? 0.0f : 0.785398f; frame_info.radian_step = k2Pi / vertices_per_geom; frame_info.points_per_circle = points_per_circle; frame_info.divisions_per_circle = vertices_per_geom; - VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); - VS::BindGeometryData( + PS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); + PS::BindGeometryData( cmd, {.buffer = buffer, .range = Range{0, total * sizeof(Point)}}); + PS::BindPointData(cmd, points_data); - cmd.BindVertices(vtx_buffer); - - // Ensure correct synchronization by submitting vertex computation into - // a different render pass. { - auto render_target = RenderTarget::CreateOffscreen( - *renderer.GetContext(), // context - {1, 1}, // size - "Geometry Snapshot", // label - RenderTarget:: - kDefaultColorAttachmentConfigNonRendering, // color_attachment_config - std::nullopt // stencil_attachment_config - ); auto cmd_buffer = renderer.GetContext()->CreateCommandBuffer(); - auto vertex_render_pass = cmd_buffer->CreateRenderPass(render_target); + auto pass = cmd_buffer->CreateComputePass(); + pass->SetGridSize(ISize(total, 1)); + pass->SetThreadGroupSize(ISize(total, 1)); - if (!vertex_render_pass->AddCommand(std::move(cmd)) || - !vertex_render_pass->EncodeCommands() || + if (!pass->AddCommand(std::move(cmd)) || !pass->EncodeCommands() || !cmd_buffer->SubmitCommands()) { return {}; } } + // cmd.BindVertices(vtx_buffer); + + // // Ensure correct synchronization by submitting vertex computation into + // // a different render pass. + // { + // auto render_target = RenderTarget::CreateOffscreen( + // *renderer.GetContext(), // context + // {1, 1}, // size + // "Geometry Snapshot", // label + // RenderTarget:: + // kDefaultColorAttachmentConfigNonRendering, // + // color_attachment_config + // std::nullopt // stencil_attachment_config + // ); + // auto cmd_buffer = renderer.GetContext()->CreateCommandBuffer(); + // auto vertex_render_pass = cmd_buffer->CreateRenderPass(render_target); + + // if (!vertex_render_pass->AddCommand(std::move(cmd)) || + // !vertex_render_pass->EncodeCommands() || + // !cmd_buffer->SubmitCommands()) { + // return {}; + // } + // } + return { .type = PrimitiveType::kTriangle, .vertex_buffer = {.vertex_buffer = {.buffer = buffer, @@ -1013,7 +1028,7 @@ std::optional PointFieldGeometry::GetCoverage( const Matrix& transform) const { if (points_.size() > 0) { // Doesn't use MakePointBounds as this isn't resilient to points that - // lie along the same axis. + // all lie along the same axis. auto first = points_.begin(); auto last = points_.end(); auto left = first->x; diff --git a/impeller/entity/shaders/geometry/points.comp b/impeller/entity/shaders/geometry/points.comp new file mode 100644 index 0000000000000..1a84951c75602 --- /dev/null +++ b/impeller/entity/shaders/geometry/points.comp @@ -0,0 +1,67 @@ +// 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 +#include + +// I dunno. +layout(local_size_x = 16) in; + +layout(std430) readonly buffer PointData { + vec2 points[]; +} +point_data; + +layout(std430) writeonly buffer GeometryData { + vec2 geometry[]; +} +geometry_data; + +uniform FrameInfo { + uint count; + float16_t radius; + float16_t radian_start; + float16_t radian_step; + uint points_per_circle; + int divisions_per_circle; +} +frame_info; + +void main() { + uint ident = gl_GlobalInvocationID.x; + // TODO(dnfield): https://github.com/flutter/flutter/issues/112683 + // We should be able to use length here instead of an extra arrgument. + if (ident >= frame_info.count) { + return; + } + + 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; + + elapsed_angle += frame_info.radian_step; + pt2 = center + + vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; + geometry_data.geometry[bufer_offset++] = pt2; + } +} From 08296cdf8e05c8e11f35ab6188c11fa19ee571c3 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 15 May 2023 15:06:18 -0700 Subject: [PATCH 27/40] remove disabled rasterization support --- impeller/entity/contents/content_context.cc | 21 --------- impeller/entity/contents/content_context.h | 10 ----- impeller/entity/geometry.cc | 34 -------------- impeller/renderer/pipeline_builder.h | 49 +++++---------------- impeller/renderer/render_target.h | 6 --- 5 files changed, 11 insertions(+), 109 deletions(-) diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 8da85ca76e20a..3e121c77afc76 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -163,22 +163,6 @@ static std::unique_ptr CreateDefaultPipeline( return std::make_unique(context, desc); } -template -static std::unique_ptr CreateDefaultNonRenderingPipeline( - const Context& context) { - auto desc = PipelineT::Builder::MakeDefaultPipelineDescriptor(context); - if (!desc.has_value()) { - return nullptr; - } - // Apply default ContentContextOptions to the descriptor. - const auto default_color_fmt = - context.GetCapabilities()->GetDefaultColorFormat(); - ContentContextOptions{.color_attachment_pixel_format = default_color_fmt, - .enable_rasterization = false} - .ApplyToPipelineDescriptor(*desc); - return std::make_unique(context, desc); -} - ContentContext::ContentContext(std::shared_ptr context) : context_(std::move(context)), tessellator_(std::make_shared()), @@ -314,11 +298,6 @@ ContentContext::ContentContext(std::shared_ptr context) porter_duff_blend_pipelines_[{}] = CreateDefaultPipeline(*context_); - if (context_->GetCapabilities()->SupportsDisabledRasterization()) { - point_field_geometry_pipelines_[{}] = - CreateDefaultNonRenderingPipeline( - *context_); - } if (context_->GetCapabilities()->SupportsCompute()) { auto pipeline_desc = PointsComputeShaderPipeline::MakeDefaultPipelineDescriptor(*context_); diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 6c9f69a1733a2..5a2df0923de5c 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -278,8 +278,6 @@ using FramebufferBlendSoftLightPipeline = FramebufferBlendSoftlightFragmentShader>; /// Geometry Pipelines -using PointFieldGeometryPipeline = - RenderPipelineT; using PointsComputeShaderPipeline = ComputePipelineBuilder; /// Pipeline state configuration. @@ -669,12 +667,6 @@ class ContentContext { return GetPipeline(framebuffer_blend_softlight_pipelines_, opts); } - std::shared_ptr> GetPointFieldGeometryPipeline( - ContentContextOptions opts) const { - FML_DCHECK(GetDeviceCapabilities().SupportsDisabledRasterization()); - return GetPipeline(point_field_geometry_pipelines_, opts); - } - std::shared_ptr> GetPointComputePipeline() const { FML_DCHECK(GetDeviceCapabilities().SupportsCompute()); @@ -806,8 +798,6 @@ class ContentContext { mutable std::shared_ptr> point_field_compute_pipelines_; - mutable Variants point_field_geometry_pipelines_; - template std::shared_ptr> GetPipeline( Variants& container, diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index fc6ca0069b0d5..20429eae6e929 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -843,8 +843,6 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( using PS = PointsComputeShader; - // using VS = PointFieldGeometryPipeline::VertexShader; - auto points_data = host_buffer.Emplace( points_.data(), points_.size() * sizeof(Point), alignof(Point)); @@ -859,14 +857,6 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( cmd.label = "Points Geometry"; cmd.pipeline = renderer.GetPointComputePipeline(); - // auto options = OptionsFromPass(pass); - // options.blend_mode = BlendMode::kSource; - // options.stencil_compare = CompareFunction::kAlways; - // options.stencil_operation = StencilOperation::kKeep; - // options.enable_rasterization = false; - // options.sample_count = SampleCount::kCount1; - // cmd.pipeline = renderer.GetPointFieldGeometryPipeline(options); - PS::FrameInfo frame_info; frame_info.count = points_.size(); frame_info.radius = radius; @@ -892,30 +882,6 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( } } - // cmd.BindVertices(vtx_buffer); - - // // Ensure correct synchronization by submitting vertex computation into - // // a different render pass. - // { - // auto render_target = RenderTarget::CreateOffscreen( - // *renderer.GetContext(), // context - // {1, 1}, // size - // "Geometry Snapshot", // label - // RenderTarget:: - // kDefaultColorAttachmentConfigNonRendering, // - // color_attachment_config - // std::nullopt // stencil_attachment_config - // ); - // auto cmd_buffer = renderer.GetContext()->CreateCommandBuffer(); - // auto vertex_render_pass = cmd_buffer->CreateRenderPass(render_target); - - // if (!vertex_render_pass->AddCommand(std::move(cmd)) || - // !vertex_render_pass->EncodeCommands() || - // !cmd_buffer->SubmitCommands()) { - // return {}; - // } - // } - return { .type = PrimitiveType::kTriangle, .vertex_buffer = {.vertex_buffer = {.buffer = buffer, diff --git a/impeller/renderer/pipeline_builder.h b/impeller/renderer/pipeline_builder.h index a567f43c23093..d3f333ca1e51c 100644 --- a/impeller/renderer/pipeline_builder.h +++ b/impeller/renderer/pipeline_builder.h @@ -16,15 +16,6 @@ namespace impeller { -class NonRenderingFragment { - public: - static constexpr std::string_view kLabel = ""; - static constexpr std::string_view kEntrypointName = ""; - static constexpr ShaderStage kShaderStage = ShaderStage::kFragment; - static constexpr std::string_view kGeneratorName = ""; - static constexpr std::array kDescriptorSetLayouts{}; -}; - //------------------------------------------------------------------------------ /// @brief An optional (but highly recommended) utility for creating /// pipelines from reflected shader information. @@ -69,40 +60,22 @@ struct PipelineBuilder { const Context& context, PipelineDescriptor& desc) { // Setup debug instrumentation. - if (!std::is_same::value) { - desc.SetLabel(SPrintF("%s Pipeline", FragmentShader::kLabel.data())); - } else { - desc.SetLabel(SPrintF("%s Pipeline", VertexShader::kLabel.data())); - } + desc.SetLabel(SPrintF("%s Pipeline", FragmentShader::kLabel.data())); // Resolve pipeline entrypoints. { auto vertex_function = context.GetShaderLibrary()->GetFunction( VertexShader::kEntrypointName, ShaderStage::kVertex); - - std::shared_ptr fragment_function; - if (!std::is_same::value) { - fragment_function = context.GetShaderLibrary()->GetFunction( - FragmentShader::kEntrypointName, ShaderStage::kFragment); - } - - if (!std::is_same::value) { - if (!vertex_function || !fragment_function) { - VALIDATION_LOG << "Could not resolve pipeline entrypoint(s) '" - << VertexShader::kEntrypointName << "' and '" - << FragmentShader::kEntrypointName - << "' for pipeline named '" << VertexShader::kLabel - << "'."; - return false; - } - } else { - if (!vertex_function) { - VALIDATION_LOG << "Could not resolve pipeline entrypoint(s) '" - << FragmentShader::kEntrypointName - << "' for pipeline named '" << VertexShader::kLabel - << "'."; - return false; - } + auto fragment_function = context.GetShaderLibrary()->GetFunction( + FragmentShader::kEntrypointName, ShaderStage::kFragment); + + if (!vertex_function || !fragment_function) { + VALIDATION_LOG << "Could not resolve pipeline entrypoint(s) '" + << VertexShader::kEntrypointName << "' and '" + << FragmentShader::kEntrypointName + << "' for pipeline named '" << VertexShader::kLabel + << "'."; + return false; } desc.AddStageEntrypoint(std::move(vertex_function)); diff --git a/impeller/renderer/render_target.h b/impeller/renderer/render_target.h index 2b44a3c9445e0..bc54976a030a8 100644 --- a/impeller/renderer/render_target.h +++ b/impeller/renderer/render_target.h @@ -53,12 +53,6 @@ class RenderTarget final { .store_action = StoreAction::kDontCare, .clear_color = Color::BlackTransparent()}; - static constexpr AttachmentConfig kDefaultColorAttachmentConfigNonRendering = - {.storage_mode = StorageMode::kDevicePrivate, - .load_action = LoadAction::kDontCare, - .store_action = StoreAction::kDontCare, - .clear_color = Color::BlackTransparent()}; - static RenderTarget CreateOffscreen( const Context& context, ISize size, From 9603338a7381ab5cef32c8f5d5c9828f13aa77f1 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 15 May 2023 15:12:01 -0700 Subject: [PATCH 28/40] ++ --- impeller/entity/contents/content_context.cc | 3 +-- impeller/entity/geometry.cc | 2 +- impeller/renderer/backend/metal/context_mtl.mm | 12 ------------ .../backend/metal/pipeline_library_mtl.mm | 1 - .../renderer/backend/vulkan/capabilities_vk.cc | 4 ---- .../renderer/backend/vulkan/capabilities_vk.h | 3 --- impeller/renderer/capabilities.cc | 15 --------------- impeller/renderer/capabilities.h | 5 ----- impeller/renderer/capabilities_unittests.cc | 1 - impeller/renderer/pipeline_descriptor.cc | 12 +----------- impeller/renderer/pipeline_descriptor.h | 5 ----- 11 files changed, 3 insertions(+), 60 deletions(-) diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 3e121c77afc76..729f2cbbc3b0d 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -11,10 +11,10 @@ #include "impeller/core/formats.h" #include "impeller/entity/entity.h" #include "impeller/renderer/command_buffer.h" +#include "impeller/renderer/pipeline_library.h" #include "impeller/renderer/render_pass.h" #include "impeller/renderer/render_target.h" #include "impeller/tessellator/tessellator.h" -#include "impeller/renderer/pipeline_library.h" namespace impeller { @@ -145,7 +145,6 @@ void ContentContextOptions::ApplyToPipelineDescriptor( desc.SetPrimitiveType(primitive_type); desc.SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill); - desc.SetEnableRasterization(enable_rasterization); } template diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index 20429eae6e929..4d0ec9e9012c2 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -831,7 +831,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( Scalar min_size = 1.0f / sqrt(std::abs(determinant)); Scalar radius = std::max(radius_, min_size); - if (!renderer.GetDeviceCapabilities().SupportsDisabledRasterization()) { + if (!renderer.GetDeviceCapabilities().SupportsCompute()) { return GetPositionBufferCPU(renderer, entity, pass, radius); } diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm index e37757e44195d..c83f5b7075c47 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -45,17 +45,6 @@ static bool DeviceSupportsComputeSubgroups(id device) { return supports_subgroups; } -static bool SupportsDisabledRasterization() { - // TOOD(jonahwilliams): on macOS playgrounds there seems to be some alignment - // issues with the device buffers but I haven't been able to trigger any sort - // of validation warnings. Disabling there for now. -#if FML_OS_IOS - return true; -#else - return false; -#endif // FML_OS_IOS -} - static std::unique_ptr InferMetalCapabilities( id device, PixelFormat color_format) { @@ -73,7 +62,6 @@ static bool SupportsDisabledRasterization() { .SetSupportsComputeSubgroups(DeviceSupportsComputeSubgroups(device)) .SetSupportsReadFromResolve(true) .SetSupportsReadFromOnscreenTexture(true) - .SetSupportsDisabledRasterization(SupportsDisabledRasterization()) .Build(); } diff --git a/impeller/renderer/backend/metal/pipeline_library_mtl.mm b/impeller/renderer/backend/metal/pipeline_library_mtl.mm index e7b74e55499e2..c65e31f1e7a43 100644 --- a/impeller/renderer/backend/metal/pipeline_library_mtl.mm +++ b/impeller/renderer/backend/metal/pipeline_library_mtl.mm @@ -27,7 +27,6 @@ auto descriptor = [[MTLRenderPipelineDescriptor alloc] init]; descriptor.label = @(desc.GetLabel().c_str()); descriptor.rasterSampleCount = static_cast(desc.GetSampleCount()); - descriptor.rasterizationEnabled = desc.GetRasterizationEnabled(); for (const auto& entry : desc.GetStageEntrypoints()) { if (entry.first == ShaderStage::kVertex) { diff --git a/impeller/renderer/backend/vulkan/capabilities_vk.cc b/impeller/renderer/backend/vulkan/capabilities_vk.cc index 1416ed07e0436..ff4410f15935a 100644 --- a/impeller/renderer/backend/vulkan/capabilities_vk.cc +++ b/impeller/renderer/backend/vulkan/capabilities_vk.cc @@ -352,10 +352,6 @@ bool CapabilitiesVK::SupportsDecalTileMode() const { return true; } -bool CapabilitiesVK::SupportsDisabledRasterization() const { - return true; -} - // |Capabilities| PixelFormat CapabilitiesVK::GetDefaultColorFormat() const { return color_format_; diff --git a/impeller/renderer/backend/vulkan/capabilities_vk.h b/impeller/renderer/backend/vulkan/capabilities_vk.h index 90d01b445bd9f..006ed6f0e0889 100644 --- a/impeller/renderer/backend/vulkan/capabilities_vk.h +++ b/impeller/renderer/backend/vulkan/capabilities_vk.h @@ -79,9 +79,6 @@ class CapabilitiesVK final : public Capabilities, // |Capabilities| bool SupportsDecalTileMode() const override; - // |Capabilities| - bool SupportsDisabledRasterization() const override; - // |Capabilities| PixelFormat GetDefaultColorFormat() const override; diff --git a/impeller/renderer/capabilities.cc b/impeller/renderer/capabilities.cc index bb41c2644261a..d0531f5f265b2 100644 --- a/impeller/renderer/capabilities.cc +++ b/impeller/renderer/capabilities.cc @@ -66,11 +66,6 @@ class StandardCapabilities final : public Capabilities { return supports_decal_tile_mode_; } - // |Capabilities| - bool SupportsDisabledRasterization() const override { - return supports_disabled_rasterization_; - } - // |Capabilities| PixelFormat GetDefaultColorFormat() const override { return default_color_format_; @@ -93,7 +88,6 @@ class StandardCapabilities final : public Capabilities { bool supports_read_from_onscreen_texture, bool supports_read_from_resolve, bool supports_decal_tile_mode, - bool supports_disabled_rasterization, PixelFormat default_color_format, PixelFormat default_stencil_format) : has_threading_restrictions_(has_threading_restrictions), @@ -108,7 +102,6 @@ class StandardCapabilities final : public Capabilities { supports_read_from_onscreen_texture), supports_read_from_resolve_(supports_read_from_resolve), supports_decal_tile_mode_(supports_decal_tile_mode), - supports_disabled_rasterization_(supports_disabled_rasterization), default_color_format_(default_color_format), default_stencil_format_(default_stencil_format) {} @@ -125,7 +118,6 @@ class StandardCapabilities final : public Capabilities { bool supports_read_from_onscreen_texture_ = false; bool supports_read_from_resolve_ = false; bool supports_decal_tile_mode_ = false; - bool supports_disabled_rasterization_ = false; PixelFormat default_color_format_ = PixelFormat::kUnknown; PixelFormat default_stencil_format_ = PixelFormat::kUnknown; @@ -210,12 +202,6 @@ CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsDecalTileMode(bool value) { return *this; } -CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsDisabledRasterization( - bool value) { - supports_disabled_rasterization_ = value; - return *this; -} - std::unique_ptr CapabilitiesBuilder::Build() { return std::unique_ptr(new StandardCapabilities( // has_threading_restrictions_, // @@ -229,7 +215,6 @@ std::unique_ptr CapabilitiesBuilder::Build() { supports_read_from_onscreen_texture_, // supports_read_from_resolve_, // supports_decal_tile_mode_, // - supports_disabled_rasterization_, // *default_color_format_, // *default_stencil_format_ // )); diff --git a/impeller/renderer/capabilities.h b/impeller/renderer/capabilities.h index a0ce72baa0f62..6fb1118dd7c95 100644 --- a/impeller/renderer/capabilities.h +++ b/impeller/renderer/capabilities.h @@ -37,8 +37,6 @@ class Capabilities { virtual bool SupportsDecalTileMode() const = 0; - virtual bool SupportsDisabledRasterization() const = 0; - virtual PixelFormat GetDefaultColorFormat() const = 0; virtual PixelFormat GetDefaultStencilFormat() const = 0; @@ -81,8 +79,6 @@ class CapabilitiesBuilder { CapabilitiesBuilder& SetSupportsDecalTileMode(bool value); - CapabilitiesBuilder& SetSupportsDisabledRasterization(bool value); - std::unique_ptr Build(); private: @@ -97,7 +93,6 @@ class CapabilitiesBuilder { bool supports_read_from_onscreen_texture_ = false; bool supports_read_from_resolve_ = false; bool supports_decal_tile_mode_ = false; - bool supports_disabled_rasterization_ = false; std::optional default_color_format_ = std::nullopt; std::optional default_stencil_format_ = std::nullopt; diff --git a/impeller/renderer/capabilities_unittests.cc b/impeller/renderer/capabilities_unittests.cc index 1b95a01481e1f..1dc9d17e3c678 100644 --- a/impeller/renderer/capabilities_unittests.cc +++ b/impeller/renderer/capabilities_unittests.cc @@ -29,7 +29,6 @@ CAPABILITY_TEST(SupportsComputeSubgroups, false); CAPABILITY_TEST(SupportsReadFromOnscreenTexture, false); CAPABILITY_TEST(SupportsReadFromResolve, false); CAPABILITY_TEST(SupportsDecalTileMode, false); -CAPABILITY_TEST(SupportsDisabledRasterization, false); } // namespace testing } // namespace impeller diff --git a/impeller/renderer/pipeline_descriptor.cc b/impeller/renderer/pipeline_descriptor.cc index a0541a60c4168..eef517b30c847 100644 --- a/impeller/renderer/pipeline_descriptor.cc +++ b/impeller/renderer/pipeline_descriptor.cc @@ -42,7 +42,6 @@ std::size_t PipelineDescriptor::GetHash() const { fml::HashCombineSeed(seed, cull_mode_); fml::HashCombineSeed(seed, primitive_type_); fml::HashCombineSeed(seed, polygon_mode_); - fml::HashCombineSeed(seed, enable_rasterization_); return seed; } @@ -62,8 +61,7 @@ bool PipelineDescriptor::IsEqual(const PipelineDescriptor& other) const { winding_order_ == other.winding_order_ && cull_mode_ == other.cull_mode_ && primitive_type_ == other.primitive_type_ && - polygon_mode_ == other.polygon_mode_ && - enable_rasterization_ == other.enable_rasterization_; + polygon_mode_ == other.polygon_mode_; } PipelineDescriptor& PipelineDescriptor::SetLabel(std::string label) { @@ -237,14 +235,6 @@ PixelFormat PipelineDescriptor::GetDepthPixelFormat() const { return depth_pixel_format_; } -void PipelineDescriptor::SetEnableRasterization(bool value) { - enable_rasterization_ = value; -} - -bool PipelineDescriptor::GetRasterizationEnabled() const { - return enable_rasterization_; -} - std::optional PipelineDescriptor::GetBackStencilAttachmentDescriptor() const { return back_stencil_attachment_descriptor_; diff --git a/impeller/renderer/pipeline_descriptor.h b/impeller/renderer/pipeline_descriptor.h index 0769c7231a585..3d0eddf880e28 100644 --- a/impeller/renderer/pipeline_descriptor.h +++ b/impeller/renderer/pipeline_descriptor.h @@ -131,10 +131,6 @@ class PipelineDescriptor final : public Comparable { PolygonMode GetPolygonMode() const; - void SetEnableRasterization(bool value); - - bool GetRasterizationEnabled() const; - private: std::string label_; SampleCount sample_count_ = SampleCount::kCount1; @@ -153,7 +149,6 @@ class PipelineDescriptor final : public Comparable { back_stencil_attachment_descriptor_; PrimitiveType primitive_type_ = PrimitiveType::kTriangle; PolygonMode polygon_mode_ = PolygonMode::kFill; - bool enable_rasterization_ = true; }; } // namespace impeller From 728a734d2fded4438f32b75ac6366487c31ef81b Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 15 May 2023 15:13:54 -0700 Subject: [PATCH 29/40] ++ --- ci/licenses_golden/licenses_flutter | 4 +- impeller/entity/BUILD.gn | 1 - impeller/entity/contents/content_context.h | 1 - impeller/entity/shaders/geometry/points.vert | 54 ----------------- impeller/tools/malioc.json | 61 -------------------- 5 files changed, 2 insertions(+), 119 deletions(-) delete mode 100644 impeller/entity/shaders/geometry/points.vert diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index e8acef0ee81c9..751265745129e 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1295,7 +1295,7 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_alp ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_alpha_nodecal.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_decal.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_nodecal.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/geometry/points.vert + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/geometry/points.comp + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas_color.frag + ../../../flutter/LICENSE @@ -3913,7 +3913,7 @@ FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_alpha FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_alpha_nodecal.frag FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_decal.frag FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_nodecal.frag -FILE: ../../../flutter/impeller/entity/shaders/geometry/points.vert +FILE: ../../../flutter/impeller/entity/shaders/geometry/points.comp FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas_color.frag diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index caaca9926cd45..7a640d4bab301 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -96,7 +96,6 @@ impeller_shaders("modern_entity_shaders") { "shaders/linear_gradient_ssbo_fill.frag", "shaders/radial_gradient_ssbo_fill.frag", "shaders/sweep_gradient_ssbo_fill.frag", - "shaders/geometry/points.vert", "shaders/geometry/points.comp", ] } diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 5a2df0923de5c..b419fa08369c7 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -40,7 +40,6 @@ #include "impeller/entity/morphology_filter.frag.h" #include "impeller/entity/morphology_filter.vert.h" #include "impeller/entity/points.comp.h" -#include "impeller/entity/points.vert.h" #include "impeller/entity/porter_duff_blend.frag.h" #include "impeller/entity/radial_gradient_fill.frag.h" #include "impeller/entity/rrect_blur.frag.h" diff --git a/impeller/entity/shaders/geometry/points.vert b/impeller/entity/shaders/geometry/points.vert deleted file mode 100644 index 6e8910cb917c9..0000000000000 --- a/impeller/entity/shaders/geometry/points.vert +++ /dev/null @@ -1,54 +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 -#include - -uniform FrameInfo { - float16_t radius; - float16_t radian_start; - float16_t radian_step; - int points_per_circle; - int divisions_per_circle; -} -frame_info; - -layout(std430) writeonly buffer GeometryData { - vec2 geometry[]; -} -geometry_data; - -in vec2 center; - -void main() { - // The buffer offset we start writing to is the number of data per circle * - // number of previous circles. - int bufer_offset = gl_VertexIndex * 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; - - elapsed_angle += frame_info.radian_step; - pt2 = center + - vec2(cos(elapsed_angle), sin(elapsed_angle)) * frame_info.radius; - geometry_data.geometry[bufer_offset++] = pt2; - } -} diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index 2361bcb96c997..0ea54a4a9d0c4 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -12067,67 +12067,6 @@ } } }, - "flutter/impeller/entity/points.vert.vkspv": { - "Mali-G78": { - "core": "Mali-G78", - "filename": "flutter/impeller/entity/points.vert.vkspv", - "has_uniform_computation": true, - "type": "Vertex", - "variants": { - "Position": { - "fp16_arithmetic": 35, - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - null - ], - "longest_path_cycles": [ - null, - null, - null, - null, - null, - null - ], - "pipelines": [ - "arith_total", - "arith_fma", - "arith_cvt", - "arith_sfu", - "load_store", - "texture" - ], - "shortest_path_bound_pipelines": [ - "load_store" - ], - "shortest_path_cycles": [ - 0.203125, - 0.046875, - 0.203125, - 0.0625, - 3.0, - 0.0 - ], - "total_bound_pipelines": [ - "load_store" - ], - "total_cycles": [ - 0.375, - 0.21875, - 0.375, - 0.1875, - 5.0, - 0.0 - ] - }, - "stack_spill_bytes": 0, - "thread_occupancy": 100, - "uniform_registers_used": 14, - "work_registers_used": 17 - } - } - } - }, "flutter/impeller/entity/porter_duff_blend.frag.vkspv": { "Mali-G78": { "core": "Mali-G78", From 92534b807d8bac813d4abbfca75cc209ccb64d2e Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 15 May 2023 15:15:40 -0700 Subject: [PATCH 30/40] ++ --- impeller/renderer/pipeline_builder.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/impeller/renderer/pipeline_builder.h b/impeller/renderer/pipeline_builder.h index d3f333ca1e51c..ccc9e9b83a9f9 100644 --- a/impeller/renderer/pipeline_builder.h +++ b/impeller/renderer/pipeline_builder.h @@ -79,9 +79,7 @@ struct PipelineBuilder { } desc.AddStageEntrypoint(std::move(vertex_function)); - if (fragment_function != nullptr) { - desc.AddStageEntrypoint(std::move(fragment_function)); - } + desc.AddStageEntrypoint(std::move(fragment_function)); } // Setup the vertex descriptor from reflected information. From e3069427ed3b814e41a28ed2fea41b1081961652 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 15 May 2023 15:22:04 -0700 Subject: [PATCH 31/40] ++ --- impeller/base/validation.cc | 2 +- impeller/entity/contents/content_context.h | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/impeller/base/validation.cc b/impeller/base/validation.cc index b58e42875c9bd..d3a7031622fef 100644 --- a/impeller/base/validation.cc +++ b/impeller/base/validation.cc @@ -11,7 +11,7 @@ namespace impeller { static std::atomic_int32_t sValidationLogsDisabledCount = 0; -static bool sValidationLogsAreFatal = true; +static bool sValidationLogsAreFatal = false; void ImpellerValidationErrorsSetFatal(bool fatal) { sValidationLogsAreFatal = fatal; diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index b419fa08369c7..efe716015fef0 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -298,14 +298,13 @@ struct ContentContextOptions { std::optional color_attachment_pixel_format; bool has_stencil_attachment = true; bool wireframe = false; - bool enable_rasterization = true; struct Hash { constexpr std::size_t operator()(const ContentContextOptions& o) const { return fml::HashCombine( o.sample_count, o.blend_mode, o.stencil_compare, o.stencil_operation, o.primitive_type, o.color_attachment_pixel_format, - o.has_stencil_attachment, o.wireframe, o.enable_rasterization); + o.has_stencil_attachment, o.wireframe); } }; @@ -320,8 +319,7 @@ struct ContentContextOptions { lhs.color_attachment_pixel_format == rhs.color_attachment_pixel_format && lhs.has_stencil_attachment == rhs.has_stencil_attachment && - lhs.wireframe == rhs.wireframe && - lhs.enable_rasterization == rhs.enable_rasterization; + lhs.wireframe == rhs.wireframe; } }; From 408642ff020ed08fcb8e0fbff16e109d3a2e4bc4 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 15 May 2023 16:00:53 -0700 Subject: [PATCH 32/40] ++ --- impeller/entity/contents/content_context.h | 8 +-- impeller/tools/malioc.json | 63 ++++++++++++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index efe716015fef0..9762b7a65f070 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -301,10 +301,10 @@ struct ContentContextOptions { struct Hash { constexpr std::size_t operator()(const ContentContextOptions& o) const { - return fml::HashCombine( - o.sample_count, o.blend_mode, o.stencil_compare, o.stencil_operation, - o.primitive_type, o.color_attachment_pixel_format, - o.has_stencil_attachment, o.wireframe); + return fml::HashCombine(o.sample_count, o.blend_mode, o.stencil_compare, + o.stencil_operation, o.primitive_type, + o.color_attachment_pixel_format, + o.has_stencil_attachment, o.wireframe); } }; diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index 0ea54a4a9d0c4..3699fdde904b2 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -12067,6 +12067,69 @@ } } }, + "flutter/impeller/entity/points.comp.vkspv": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/points.comp.vkspv", + "has_uniform_computation": true, + "type": "Compute", + "variants": { + "Main": { + "fp16_arithmetic": 35, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + null + ], + "longest_path_cycles": [ + null, + null, + null, + null, + null, + null + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "arith_total", + "arith_cvt" + ], + "shortest_path_cycles": [ + 0.046875, + 0.0, + 0.046875, + 0.0, + 0.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 0.453125, + 0.21875, + 0.453125, + 0.1875, + 5.0, + 0.0 + ] + }, + "shared_storage_used": 0, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 16, + "work_registers_used": 17 + } + } + } + }, "flutter/impeller/entity/porter_duff_blend.frag.vkspv": { "Mali-G78": { "core": "Mali-G78", From 4a44b460f9bddf1b851eacce5317d21fc8056bf0 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 15 May 2023 16:14:21 -0700 Subject: [PATCH 33/40] add golden for drawPoints --- impeller/aiks/aiks_unittests.cc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 5858719b6c8cd..9c23f14abc5a1 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -2165,5 +2165,31 @@ TEST_P(AiksTest, CanRenderDestructiveSaveLayer) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } +TEST_P(AiksTest, CanDrawPoints) { + std::vector points = { + {0, 0}, // + {100, 100}, // + {100, 0}, // + {0, 100}, // + {0, 0}, // + {48, 48}, // + {52, 52}, // + }; + std::vector caps = { + PointStyle::kRound, + PointStyle::kSquare, + }; + Paint paint; + paint.color = Color::Yellow().WithAlpha(0.5); + + Canvas canvas; + canvas.Translate({200, 200}); + canvas.DrawPoints(points, 10, paint, PointStyle::kRound); + canvas.Translate({150, 0}); + canvas.DrawPoints(points, 10, paint, PointStyle::kSquare); + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + } // namespace testing } // namespace impeller From c9072603f83f712ef2d788906994395cc6940f35 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 18 May 2023 15:11:06 -0700 Subject: [PATCH 34/40] dnfield review --- impeller/entity/entity_unittests.cc | 19 +++++++++++++++++++ impeller/entity/geometry.cc | 8 ++++---- impeller/entity/geometry.h | 4 ++-- impeller/entity/shaders/geometry/points.comp | 6 +++--- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 999d1f0132071..ebef3accd811e 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -2612,5 +2612,24 @@ TEST_P(EntityTest, TessellateConvex) { } } +TEST_P(EntityTest, PointFieldGeometryDivisions) { + // 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); + // Caps at 140. + ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1000.0, true), 140u); + ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(20000.0, true), 140u); +} + } // namespace testing } // namespace impeller diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index 4d0ec9e9012c2..df61279d7f98e 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -860,7 +860,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( PS::FrameInfo frame_info; frame_info.count = points_.size(); frame_info.radius = radius; - frame_info.radian_start = round_ ? 0.0f : 0.785398f; + frame_info.radian_start = round_ ? 0.0f : kPiOver4; frame_info.radian_step = k2Pi / vertices_per_geom; frame_info.points_per_circle = points_per_circle; frame_info.divisions_per_circle = vertices_per_geom; @@ -958,9 +958,9 @@ GeometryResult PointFieldGeometry::GetPositionUVBuffer( FML_UNREACHABLE(); } -/// @brief Compute the exact storage size needed to store the resulting -/// buffer. -/// @return +/// @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) { if (!round) { diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index cac8007a6ba58..6ffa6c5991c3b 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -270,6 +270,8 @@ class PointFieldGeometry : public Geometry { ~PointFieldGeometry(); + static size_t ComputeCircleDivisions(Scalar scaled_radius, bool round); + private: // |Geometry| GeometryResult GetPositionBuffer(const ContentContext& renderer, @@ -289,8 +291,6 @@ class PointFieldGeometry : public Geometry { // |Geometry| std::optional GetCoverage(const Matrix& transform) const override; - static size_t ComputeCircleDivisions(Scalar scaled_radius, bool round); - GeometryResult GetPositionBufferCPU(const ContentContext& renderer, const Entity& entity, RenderPass& pass, diff --git a/impeller/entity/shaders/geometry/points.comp b/impeller/entity/shaders/geometry/points.comp index 1a84951c75602..7d274ade49948 100644 --- a/impeller/entity/shaders/geometry/points.comp +++ b/impeller/entity/shaders/geometry/points.comp @@ -5,15 +5,17 @@ #include #include -// I dunno. +// Unused, see See PointFieldGeometry::GetPositionBuffer layout(local_size_x = 16) in; layout(std430) readonly buffer PointData { + // Size of this input data is frame_info.count; vec2 points[]; } point_data; layout(std430) writeonly buffer GeometryData { + // Size of this output data is frame_info.count * points_per_circle; vec2 geometry[]; } geometry_data; @@ -30,8 +32,6 @@ frame_info; void main() { uint ident = gl_GlobalInvocationID.x; - // TODO(dnfield): https://github.com/flutter/flutter/issues/112683 - // We should be able to use length here instead of an extra arrgument. if (ident >= frame_info.count) { return; } From 40ef2b4c024099c1a3452abb251d4c5f85ea3dd2 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 18 May 2023 15:11:39 -0700 Subject: [PATCH 35/40] ++ --- impeller/entity/entity_unittests.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index ebef3accd811e..b9b58f367a573 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -2618,7 +2618,6 @@ TEST_P(EntityTest, PointFieldGeometryDivisions) { 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); From 14e76fcb96e0f1e13ff8849fa500bafcf645cb93 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 18 May 2023 21:10:35 -0700 Subject: [PATCH 36/40] fix threadgroup size for 1d dispatch --- .../backend/metal/compute_pass_mtl.mm | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/impeller/renderer/backend/metal/compute_pass_mtl.mm b/impeller/renderer/backend/metal/compute_pass_mtl.mm index 3a610acd154d4..15e03bd911656 100644 --- a/impeller/renderer/backend/metal/compute_pass_mtl.mm +++ b/impeller/renderer/backend/metal/compute_pass_mtl.mm @@ -248,17 +248,29 @@ static bool Bind(ComputePassBindingsCache& pass, // https://github.com/flutter/flutter/issues/110619 // For now, check that the sizes are uniform. - FML_DCHECK(grid_size == thread_group_size); + // FML_DCHECK(grid_size == thread_group_size); auto width = grid_size.width; auto height = grid_size.height; - while (width * height > - static_cast( - pass_bindings.GetPipeline().maxTotalThreadsPerThreadgroup)) { - width = std::max(1LL, width / 2); - height = std::max(1LL, height / 2); + + auto maxTotalThreadsPerThreadgroup = static_cast( + pass_bindings.GetPipeline().maxTotalThreadsPerThreadgroup); + + // Special case for linear processing. + if (height == 1) { + int64_t threadGroups = + std::max(width / maxTotalThreadsPerThreadgroup, 1LL); + [encoder dispatchThreadgroups:MTLSizeMake(threadGroups, 1, 1) + threadsPerThreadgroup:MTLSizeMake(maxTotalThreadsPerThreadgroup, + 1, 1)]; + } else { + while (width * height > maxTotalThreadsPerThreadgroup) { + width = std::max(1LL, width / 2); + height = std::max(1LL, height / 2); + } + + auto size = MTLSizeMake(width, height, 1); + [encoder dispatchThreadgroups:size threadsPerThreadgroup:size]; } - auto size = MTLSizeMake(width, height, 1); - [encoder dispatchThreadgroups:size threadsPerThreadgroup:size]; } return true; From 6e82927974bfe127cdf8fa4c2992135d85d5c5b7 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 18 May 2023 21:14:52 -0700 Subject: [PATCH 37/40] Remove commented out code --- impeller/renderer/backend/metal/compute_pass_mtl.mm | 3 --- 1 file changed, 3 deletions(-) diff --git a/impeller/renderer/backend/metal/compute_pass_mtl.mm b/impeller/renderer/backend/metal/compute_pass_mtl.mm index 15e03bd911656..d0c4d3b3b005f 100644 --- a/impeller/renderer/backend/metal/compute_pass_mtl.mm +++ b/impeller/renderer/backend/metal/compute_pass_mtl.mm @@ -246,9 +246,6 @@ static bool Bind(ComputePassBindingsCache& pass, // TODO(dnfield): use feature detection to support non-uniform threadgroup // sizes. // https://github.com/flutter/flutter/issues/110619 - - // For now, check that the sizes are uniform. - // FML_DCHECK(grid_size == thread_group_size); auto width = grid_size.width; auto height = grid_size.height; From 96921e2710843a32797c8859b588389889e03c5f Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 18 May 2023 22:00:22 -0700 Subject: [PATCH 38/40] dont use std numeric limits --- impeller/renderer/compute_unittests.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/impeller/renderer/compute_unittests.cc b/impeller/renderer/compute_unittests.cc index 1ad1dec214924..90772603af048 100644 --- a/impeller/renderer/compute_unittests.cc +++ b/impeller/renderer/compute_unittests.cc @@ -204,7 +204,7 @@ TEST_P(ComputeTest, MultiStageInputAndOutput) { latch.Wait(); } -TEST_P(ComputeTest, CanCorrectlyDownScaleLargeGridSize) { +TEST_P(ComputeTest, CanCompute1DimensionalData) { using CS = SampleComputeShader; auto context = GetContext(); ASSERT_TRUE(context); @@ -224,10 +224,7 @@ TEST_P(ComputeTest, CanCorrectlyDownScaleLargeGridSize) { static constexpr size_t kCount = 5; - // Intentionally making the grid size obscenely large. No GPU will tolerate - // this. - pass->SetGridSize(ISize(std::numeric_limits::max(), 1)); - pass->SetThreadGroupSize(ISize(std::numeric_limits::max(), 1)); + pass->SetGridSize(ISize(kCount, 1)); ComputeCommand cmd; cmd.label = "Compute"; From 0275a101dfc2f73355cac3e366e8dcb5f7b7d69f Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 18 May 2023 22:14:58 -0700 Subject: [PATCH 39/40] ++ --- impeller/renderer/backend/metal/compute_pass_mtl.mm | 4 ++++ impeller/renderer/compute_unittests.cc | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/impeller/renderer/backend/metal/compute_pass_mtl.mm b/impeller/renderer/backend/metal/compute_pass_mtl.mm index d0c4d3b3b005f..5e461a8d0e764 100644 --- a/impeller/renderer/backend/metal/compute_pass_mtl.mm +++ b/impeller/renderer/backend/metal/compute_pass_mtl.mm @@ -211,6 +211,10 @@ static bool Bind(ComputePassBindingsCache& pass, id encoder, const ISize& grid_size, const ISize& thread_group_size) const { + if (grid_size.width == 0 || grid_size.height == 0) { + return true; + } + ComputePassBindingsCache pass_bindings(encoder); fml::closure pop_debug_marker = [encoder]() { [encoder popDebugGroup]; }; diff --git a/impeller/renderer/compute_unittests.cc b/impeller/renderer/compute_unittests.cc index 90772603af048..4dd22ef28a380 100644 --- a/impeller/renderer/compute_unittests.cc +++ b/impeller/renderer/compute_unittests.cc @@ -302,7 +302,7 @@ TEST_P(ComputeTest, ReturnsEarlyWhenAnyGridDimensionIsZero) { static constexpr size_t kCount = 5; - // Intentionally making the grid size obscenely large. No GPU will tolerate + // Intentionally making the grid size zero in one dimension. No GPU will tolerate // this. pass->SetGridSize(ISize(0, 1)); pass->SetThreadGroupSize(ISize(0, 1)); From e4fae27cca0ec262b5731b5184fad412154b05d2 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 18 May 2023 22:47:16 -0700 Subject: [PATCH 40/40] ++ --- impeller/renderer/compute_unittests.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/renderer/compute_unittests.cc b/impeller/renderer/compute_unittests.cc index 4dd22ef28a380..8790396f5aefd 100644 --- a/impeller/renderer/compute_unittests.cc +++ b/impeller/renderer/compute_unittests.cc @@ -302,8 +302,8 @@ TEST_P(ComputeTest, ReturnsEarlyWhenAnyGridDimensionIsZero) { static constexpr size_t kCount = 5; - // Intentionally making the grid size zero in one dimension. No GPU will tolerate - // this. + // Intentionally making the grid size zero in one dimension. No GPU will + // tolerate this. pass->SetGridSize(ISize(0, 1)); pass->SetThreadGroupSize(ISize(0, 1));