From f9f1e3e3f4e134556b21cff500987e572ee8d344 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 6 May 2024 13:13:50 -0700 Subject: [PATCH 1/2] ++ --- impeller/BUILD.gn | 4 - .../entity/contents/solid_color_contents.h | 4 - impeller/geometry/gradient.h | 3 - impeller/renderer/BUILD.gn | 21 - .../renderer/compute_subgroup_unittests.cc | 473 ------------------ impeller/renderer/compute_tessellator.cc | 181 ------- impeller/renderer/compute_tessellator.h | 89 ---- impeller/renderer/path_polyline.comp | 170 ------- impeller/renderer/stroke.comp | 60 --- 9 files changed, 1005 deletions(-) delete mode 100644 impeller/renderer/compute_subgroup_unittests.cc delete mode 100644 impeller/renderer/compute_tessellator.cc delete mode 100644 impeller/renderer/compute_tessellator.h delete mode 100644 impeller/renderer/path_polyline.comp delete mode 100644 impeller/renderer/stroke.comp diff --git a/impeller/BUILD.gn b/impeller/BUILD.gn index accabd97e2ad7..8e7aee9978027 100644 --- a/impeller/BUILD.gn +++ b/impeller/BUILD.gn @@ -113,10 +113,6 @@ impeller_component("impeller_unittests") { "//third_party/vulkan_validation_layers:vulkan_gen_json_files", ] } - - if (impeller_enable_compute) { - deps += [ "renderer:compute_tessellation_unittests" ] - } } if (impeller_supports_rendering) { diff --git a/impeller/entity/contents/solid_color_contents.h b/impeller/entity/contents/solid_color_contents.h index 59358ac68f3f4..db5abdda94097 100644 --- a/impeller/entity/contents/solid_color_contents.h +++ b/impeller/entity/contents/solid_color_contents.h @@ -14,10 +14,6 @@ namespace impeller { -class Path; -class HostBuffer; -struct VertexBuffer; - class SolidColorContents final : public ColorSourceContents { public: SolidColorContents(); diff --git a/impeller/geometry/gradient.h b/impeller/geometry/gradient.h index 8d6e70a2e3f3c..551ec129f0a2f 100644 --- a/impeller/geometry/gradient.h +++ b/impeller/geometry/gradient.h @@ -6,12 +6,9 @@ #define FLUTTER_IMPELLER_GEOMETRY_GRADIENT_H_ #include -#include #include #include "impeller/geometry/color.h" -#include "impeller/geometry/path.h" -#include "impeller/geometry/point.h" namespace impeller { diff --git a/impeller/renderer/BUILD.gn b/impeller/renderer/BUILD.gn index 368c037eca845..5ffb79ec9135c 100644 --- a/impeller/renderer/BUILD.gn +++ b/impeller/renderer/BUILD.gn @@ -20,27 +20,10 @@ if (impeller_enable_compute) { } shaders = [ - "stroke.comp", - "path_polyline.comp", "prefix_sum_test.comp", "threadgroup_sizing_test.comp", ] } - - impeller_component("compute_tessellation_unittests") { - testonly = true - sources = [ "compute_subgroup_unittests.cc" ] - - deps = [ - ":compute_shaders", - ":renderer", - "../display_list:skia_conversions", - "../entity", - "../fixtures", - "../playground:playground_test", - "//flutter/testing:testing_lib", - ] - } } impeller_component("renderer") { @@ -109,10 +92,6 @@ impeller_component("renderer") { ] if (impeller_enable_compute) { - sources += [ - "compute_tessellator.cc", - "compute_tessellator.h", - ] public_deps += [ ":compute_shaders" ] } diff --git a/impeller/renderer/compute_subgroup_unittests.cc b/impeller/renderer/compute_subgroup_unittests.cc deleted file mode 100644 index c34a531893c05..0000000000000 --- a/impeller/renderer/compute_subgroup_unittests.cc +++ /dev/null @@ -1,473 +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 - -#include "compute_tessellator.h" -#include "flutter/fml/synchronization/waitable_event.h" -#include "flutter/fml/time/time_point.h" -#include "flutter/testing/testing.h" -#include "gmock/gmock.h" -#include "impeller/base/strings.h" -#include "impeller/core/formats.h" -#include "impeller/core/host_buffer.h" -#include "impeller/display_list/skia_conversions.h" -#include "impeller/entity/contents/content_context.h" -#include "impeller/fixtures/golden_paths.h" -#include "impeller/fixtures/sample.comp.h" -#include "impeller/fixtures/stage1.comp.h" -#include "impeller/fixtures/stage2.comp.h" -#include "impeller/geometry/path.h" -#include "impeller/geometry/path_builder.h" -#include "impeller/geometry/path_component.h" -#include "impeller/playground/compute_playground_test.h" -#include "impeller/renderer/command_buffer.h" -#include "impeller/renderer/compute_pipeline_builder.h" -#include "impeller/renderer/compute_tessellator.h" -#include "impeller/renderer/path_polyline.comp.h" -#include "impeller/renderer/pipeline_library.h" -#include "impeller/renderer/render_pass.h" -#include "impeller/renderer/stroke.comp.h" -#include "third_party/imgui/imgui.h" -#include "third_party/skia/include/utils/SkParsePath.h" - -namespace impeller { -namespace testing { - -using ComputeSubgroupTest = ComputePlaygroundTest; -INSTANTIATE_COMPUTE_SUITE(ComputeSubgroupTest); - -TEST_P(ComputeSubgroupTest, CapabilitiesSuportSubgroups) { - auto context = GetContext(); - ASSERT_TRUE(context); - ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups()); -} - -TEST_P(ComputeSubgroupTest, PathPlayground) { - // Renders stroked SVG paths in an interactive playground. - using SS = StrokeComputeShader; - - auto context = GetContext(); - ASSERT_TRUE(context); - ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups()); - char svg_path_data[16384] = - "M140 20 " - "C73 20 20 74 20 140 " - "c0 135 136 170 228 303 " - "88-132 229-173 229-303 " - "0-66-54-120-120-120 " - "-48 0-90 28-109 69 " - "-19-41-60-69-108-69z"; - size_t vertex_count = 0; - Scalar stroke_width = 1.0; - - auto vertex_buffer = CreateHostVisibleDeviceBuffer>( - context, "VertexBuffer"); - auto vertex_buffer_count = - CreateHostVisibleDeviceBuffer(context, - "VertexCount"); - - auto callback = [&](RenderPass& pass) -> bool { - ::memset(vertex_buffer_count->OnGetContents(), 0, - sizeof(SS::VertexBufferCount)); - ::memset(vertex_buffer->OnGetContents(), 0, sizeof(SS::VertexBuffer<2048>)); - const auto* main_viewport = ImGui::GetMainViewport(); - ImGui::SetNextWindowPos( - ImVec2(main_viewport->WorkPos.x + 650, main_viewport->WorkPos.y + 20)); - ImGui::Begin("Path data", nullptr, ImGuiWindowFlags_AlwaysAutoResize); - ImGui::InputTextMultiline("Path", svg_path_data, - IM_ARRAYSIZE(svg_path_data)); - ImGui::DragFloat("Stroke width", &stroke_width, .1, 0.0, 25.0); - - SkPath sk_path; - if (SkParsePath::FromSVGString(svg_path_data, &sk_path)) { - std::promise promise; - auto future = promise.get_future(); - - auto path = skia_conversions::ToPath(sk_path); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); - auto status = - ComputeTessellator{} - .SetStrokeWidth(stroke_width) - .Tessellate(path, *host_buffer, context, - DeviceBuffer::AsBufferView(vertex_buffer), - DeviceBuffer::AsBufferView(vertex_buffer_count), - [vertex_buffer_count, &vertex_count, - &promise](CommandBuffer::Status status) { - vertex_count = - reinterpret_cast( - vertex_buffer_count->OnGetContents()) - ->count; - promise.set_value( - status == CommandBuffer::Status::kCompleted); - }); - switch (status) { - case ComputeTessellator::Status::kCommandInvalid: - ImGui::Text("Failed to submit compute job (invalid command)"); - break; - case ComputeTessellator::Status::kTooManyComponents: - ImGui::Text("Failed to submit compute job (too many components) "); - break; - case ComputeTessellator::Status::kOk: - break; - } - if (!future.get()) { - ImGui::Text("Failed to submit compute job."); - return false; - } - if (vertex_count > 0) { - ImGui::Text("Vertex count: %zu", vertex_count); - } - } else { - ImGui::Text("Failed to parse path data"); - } - ImGui::End(); - - ContentContext renderer(context, nullptr); - if (!renderer.IsValid()) { - return false; - } - - using VS = SolidFillPipeline::VertexShader; - - pass.SetCommandLabel("Draw Stroke"); - pass.SetStencilReference(0); - - ContentContextOptions options; - options.sample_count = pass.GetRenderTarget().GetSampleCount(); - options.color_attachment_pixel_format = - pass.GetRenderTarget().GetRenderTargetPixelFormat(); - options.has_depth_stencil_attachments = - pass.GetRenderTarget().GetStencilAttachment().has_value(); - options.blend_mode = BlendMode::kSourceIn; - options.primitive_type = PrimitiveType::kTriangleStrip; - - options.stencil_mode = - ContentContextOptions::StencilMode::kOverdrawPreventionIncrement; - - pass.SetPipeline(renderer.GetSolidFillPipeline(options)); - - auto count = reinterpret_cast( - vertex_buffer_count->OnGetContents()) - ->count; - - pass.SetVertexBuffer( - VertexBuffer{.vertex_buffer = DeviceBuffer::AsBufferView(vertex_buffer), - .vertex_count = count, - .index_type = IndexType::kNone}); - - VS::FrameInfo frame_info; - auto world_matrix = Matrix::MakeScale(GetContentScale()); - frame_info.mvp = pass.GetOrthographicTransform() * world_matrix; - frame_info.color = Color::Red().Premultiply(); - VS::BindFrameInfo( - pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - - return pass.Draw().ok(); - }; - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - -TEST_P(ComputeSubgroupTest, LargePath) { - // The path in here is large enough to highlight issues around exceeding - // subgroup size. - using SS = StrokeComputeShader; - - auto context = GetContext(); - ASSERT_TRUE(context); - ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups()); - size_t vertex_count = 0; - Scalar stroke_width = 1.0; - - auto vertex_buffer = CreateHostVisibleDeviceBuffer>( - context, "VertexBuffer"); - auto vertex_buffer_count = - CreateHostVisibleDeviceBuffer(context, - "VertexCount"); - - auto complex_path = - PathBuilder{} - .MoveTo({359.934, 96.6335}) - .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908}, - {354.673, 96.8895}) - .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016}, - {354.367, 96.9075}) - .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113}, - {349.259, 97.2355}) - .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678}, - {348.625, 97.2834}) - .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299}, - {343.789, 97.6722}) - .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402}, - {342.703, 97.7734}) - .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505}, - {338.246, 98.207}) - .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292}, - {336.612, 98.3894}) - .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837}, - {332.623, 98.8476}) - .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818}, - {332.237, 98.8982}) - .LineTo({332.237, 102.601}) - .LineTo({321.778, 102.601}) - .LineTo({321.778, 100.382}) - .CubicCurveTo({321.572, 100.413}, {321.367, 100.442}, - {321.161, 100.476}) - .CubicCurveTo({319.22, 100.79}, {317.277, 101.123}, - {315.332, 101.479}) - .CubicCurveTo({315.322, 101.481}, {315.311, 101.482}, - {315.301, 101.484}) - .LineTo({310.017, 105.94}) - .LineTo({309.779, 105.427}) - .LineTo({314.403, 101.651}) - .CubicCurveTo({314.391, 101.653}, {314.379, 101.656}, - {314.368, 101.658}) - .CubicCurveTo({312.528, 102.001}, {310.687, 102.366}, - {308.846, 102.748}) - .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4}) - .CubicCurveTo({305.048, 103.579}, {304.236, 103.75}, - {303.425, 103.936}) - .LineTo({299.105, 107.578}) - .LineTo({298.867, 107.065}) - .LineTo({302.394, 104.185}) - .LineTo({302.412, 104.171}) - .CubicCurveTo({301.388, 104.409}, {300.366, 104.67}, - {299.344, 104.921}) - .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455}) - .CubicCurveTo({295.262, 105.94}, {293.36, 106.445}, - {291.462, 106.979}) - .CubicCurveTo({291.132, 107.072}, {290.802, 107.163}, - {290.471, 107.257}) - .CubicCurveTo({289.463, 107.544}, {288.455, 107.839}, - {287.449, 108.139}) - .CubicCurveTo({286.476, 108.431}, {285.506, 108.73}, - {284.536, 109.035}) - .CubicCurveTo({283.674, 109.304}, {282.812, 109.579}, - {281.952, 109.859}) - .CubicCurveTo({281.177, 110.112}, {280.406, 110.377}, - {279.633, 110.638}) - .CubicCurveTo({278.458, 111.037}, {277.256, 111.449}, - {276.803, 111.607}) - .CubicCurveTo({276.76, 111.622}, {276.716, 111.637}, - {276.672, 111.653}) - .CubicCurveTo({275.017, 112.239}, {273.365, 112.836}, - {271.721, 113.463}) - .LineTo({271.717, 113.449}) - .CubicCurveTo({271.496, 113.496}, {271.238, 113.559}, - {270.963, 113.628}) - .CubicCurveTo({270.893, 113.645}, {270.822, 113.663}, - {270.748, 113.682}) - .CubicCurveTo({270.468, 113.755}, {270.169, 113.834}, - {269.839, 113.926}) - .CubicCurveTo({269.789, 113.94}, {269.732, 113.957}, - {269.681, 113.972}) - .CubicCurveTo({269.391, 114.053}, {269.081, 114.143}, - {268.756, 114.239}) - .CubicCurveTo({268.628, 114.276}, {268.5, 114.314}, - {268.367, 114.354}) - .CubicCurveTo({268.172, 114.412}, {267.959, 114.478}, - {267.752, 114.54}) - .CubicCurveTo({263.349, 115.964}, {258.058, 117.695}, - {253.564, 119.252}) - .CubicCurveTo({253.556, 119.255}, {253.547, 119.258}, - {253.538, 119.261}) - .CubicCurveTo({251.844, 119.849}, {250.056, 120.474}, - {248.189, 121.131}) - .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331}) - .CubicCurveTo({247.079, 121.522}, {246.531, 121.715}, - {245.975, 121.912}) - .CubicCurveTo({245.554, 122.06}, {245.126, 122.212}, - {244.698, 122.364}) - .CubicCurveTo({244.071, 122.586}, {243.437, 122.811}, - {242.794, 123.04}) - .CubicCurveTo({242.189, 123.255}, {241.58, 123.472}, - {240.961, 123.693}) - .CubicCurveTo({240.659, 123.801}, {240.357, 123.909}, - {240.052, 124.018}) - .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032}) - .LineTo({237.164, 125.003}) - .CubicCurveTo({236.709, 125.184}, {236.262, 125.358}, - {235.81, 125.538}) - .CubicCurveTo({235.413, 125.68}, {234.994, 125.832}, - {234.592, 125.977}) - .CubicCurveTo({234.592, 125.977}, {234.591, 125.977}, - {234.59, 125.977}) - .CubicCurveTo({222.206, 130.435}, {207.708, 135.753}, - {192.381, 141.429}) - .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160}) - .LineTo({360, 160}) - .LineTo({360, 119.256}) - .LineTo({360, 106.332}) - .LineTo({360, 96.6307}) - .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326}, - {359.934, 96.6335}) - .Close() - .TakePath(); - - auto callback = [&](RenderPass& pass) -> bool { - ::memset(vertex_buffer_count->OnGetContents(), 0, - sizeof(SS::VertexBufferCount)); - ::memset(vertex_buffer->OnGetContents(), 0, sizeof(SS::VertexBuffer<2048>)); - - ContentContext renderer(context, nullptr); - if (!renderer.IsValid()) { - return false; - } - - ComputeTessellator{} - .SetStrokeWidth(stroke_width) - .Tessellate( - complex_path, renderer.GetTransientsBuffer(), context, - DeviceBuffer::AsBufferView(vertex_buffer), - DeviceBuffer::AsBufferView(vertex_buffer_count), - [vertex_buffer_count, &vertex_count](CommandBuffer::Status status) { - vertex_count = reinterpret_cast( - vertex_buffer_count->OnGetContents()) - ->count; - }); - - using VS = SolidFillPipeline::VertexShader; - - pass.SetCommandLabel("Draw Stroke"); - pass.SetStencilReference(0); - - ContentContextOptions options; - options.sample_count = pass.GetRenderTarget().GetSampleCount(); - options.color_attachment_pixel_format = - pass.GetRenderTarget().GetRenderTargetPixelFormat(); - options.has_depth_stencil_attachments = - pass.GetRenderTarget().GetStencilAttachment().has_value(); - options.blend_mode = BlendMode::kSourceIn; - options.primitive_type = PrimitiveType::kTriangleStrip; - - options.stencil_mode = - ContentContextOptions::StencilMode::kOverdrawPreventionIncrement; - - pass.SetPipeline(renderer.GetSolidFillPipeline(options)); - - auto count = reinterpret_cast( - vertex_buffer_count->OnGetContents()) - ->count; - - pass.SetVertexBuffer( - VertexBuffer{.vertex_buffer = DeviceBuffer::AsBufferView(vertex_buffer), - .vertex_count = count, - .index_type = IndexType::kNone}); - - VS::FrameInfo frame_info; - auto world_matrix = Matrix::MakeScale(GetContentScale()); - frame_info.mvp = pass.GetOrthographicTransform() * world_matrix; - frame_info.color = Color::Red().Premultiply(); - VS::BindFrameInfo( - pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - - return pass.Draw().ok(); - }; - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - -TEST_P(ComputeSubgroupTest, QuadAndCubicInOnePath) { - using SS = StrokeComputeShader; - - auto context = GetContext(); - ASSERT_TRUE(context); - ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups()); - - auto vertex_buffer = CreateHostVisibleDeviceBuffer>( - context, "VertexBuffer"); - auto vertex_buffer_count = - CreateHostVisibleDeviceBuffer(context, - "VertexBufferCount"); - - auto path = PathBuilder{} - .AddCubicCurve({140, 20}, {73, 20}, {20, 74}, {20, 140}) - .AddQuadraticCurve({20, 140}, {93, 90}, {100, 42}) - .TakePath(); - - auto tessellator = ComputeTessellator{}; - - fml::AutoResetWaitableEvent latch; - - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); - auto status = tessellator.Tessellate( - path, *host_buffer, context, DeviceBuffer::AsBufferView(vertex_buffer), - DeviceBuffer::AsBufferView(vertex_buffer_count), - [&latch](CommandBuffer::Status status) { - EXPECT_EQ(status, CommandBuffer::Status::kCompleted); - latch.Signal(); - }); - - ASSERT_EQ(status, ComputeTessellator::Status::kOk); - - auto callback = [&](RenderPass& pass) -> bool { - ContentContext renderer(context, nullptr); - if (!renderer.IsValid()) { - return false; - } - - using VS = SolidFillPipeline::VertexShader; - - pass.SetCommandLabel("Draw Stroke"); - pass.SetStencilReference(0); - - ContentContextOptions options; - options.sample_count = pass.GetRenderTarget().GetSampleCount(); - options.color_attachment_pixel_format = - pass.GetRenderTarget().GetRenderTargetPixelFormat(); - options.has_depth_stencil_attachments = - pass.GetRenderTarget().GetStencilAttachment().has_value(); - options.blend_mode = BlendMode::kSourceIn; - options.primitive_type = PrimitiveType::kTriangleStrip; - - options.stencil_mode = - ContentContextOptions::StencilMode::kOverdrawPreventionIncrement; - - pass.SetPipeline(renderer.GetSolidFillPipeline(options)); - - auto count = reinterpret_cast( - vertex_buffer_count->OnGetContents()) - ->count; - - pass.SetVertexBuffer( - VertexBuffer{.vertex_buffer = DeviceBuffer::AsBufferView(vertex_buffer), - .vertex_count = count, - .index_type = IndexType::kNone}); - - VS::FrameInfo frame_info; - auto world_matrix = Matrix::MakeScale(GetContentScale()); - frame_info.mvp = pass.GetOrthographicTransform() * world_matrix; - frame_info.color = Color::Red().Premultiply(); - VS::BindFrameInfo( - pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); - - return pass.Draw().ok(); - }; - ASSERT_TRUE(OpenPlaygroundHere(callback)); - - // The latch is down here because it's expected that on Metal the backend - // will take care of synchronizing the buffer between the compute and render - // pass usages, since it's not MTLHeap allocated. However, if playgrounds - // are disabled, no render pass actually gets submitted and we need to do a - // CPU latch here. - latch.Wait(); - - auto vertex_count = reinterpret_cast( - vertex_buffer_count->OnGetContents()) - ->count; - EXPECT_EQ(vertex_count, golden_cubic_and_quad_points.size()); - auto vertex_buffer_data = - reinterpret_cast*>(vertex_buffer->OnGetContents()); - for (size_t i = 0; i < vertex_count; i++) { - EXPECT_LT(std::abs(golden_cubic_and_quad_points[i].x - - vertex_buffer_data->position[i].x), - 1e-3); - EXPECT_LT(std::abs(golden_cubic_and_quad_points[i].y - - vertex_buffer_data->position[i].y), - 1e-3); - } -} - -} // namespace testing -} // namespace impeller diff --git a/impeller/renderer/compute_tessellator.cc b/impeller/renderer/compute_tessellator.cc deleted file mode 100644 index 8e8d084e7a2cd..0000000000000 --- a/impeller/renderer/compute_tessellator.cc +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "impeller/renderer/compute_tessellator.h" - -#include - -#include "impeller/core/host_buffer.h" -#include "impeller/renderer/command_buffer.h" -#include "impeller/renderer/path_polyline.comp.h" -#include "impeller/renderer/pipeline_library.h" -#include "impeller/renderer/stroke.comp.h" - -namespace impeller { - -ComputeTessellator::ComputeTessellator() = default; -ComputeTessellator::~ComputeTessellator() = default; - -template -static std::shared_ptr CreateDeviceBuffer( - const std::shared_ptr& context, - const std::string& label, - StorageMode storage_mode = StorageMode::kDevicePrivate) { - DeviceBufferDescriptor desc; - desc.storage_mode = storage_mode; - desc.size = sizeof(T); - auto buffer = context->GetResourceAllocator()->CreateBuffer(desc); - buffer->SetLabel(label); - return buffer; -} - -ComputeTessellator& ComputeTessellator::SetStyle(Style value) { - style_ = value; - return *this; -} - -ComputeTessellator& ComputeTessellator::SetStrokeWidth(Scalar value) { - stroke_width_ = value; - return *this; -} - -ComputeTessellator& ComputeTessellator::SetStrokeJoin(Join value) { - stroke_join_ = value; - return *this; -} -ComputeTessellator& ComputeTessellator::SetStrokeCap(Cap value) { - stroke_cap_ = value; - return *this; -} -ComputeTessellator& ComputeTessellator::SetMiterLimit(Scalar value) { - miter_limit_ = value; - return *this; -} -ComputeTessellator& ComputeTessellator::SetCubicAccuracy(Scalar value) { - cubic_accuracy_ = value; - return *this; -} -ComputeTessellator& ComputeTessellator::SetQuadraticTolerance(Scalar value) { - quad_tolerance_ = value; - return *this; -} - -ComputeTessellator::Status ComputeTessellator::Tessellate( - const Path& path, - HostBuffer& host_buffer, - const std::shared_ptr& context, - BufferView vertex_buffer, - BufferView vertex_buffer_count, - const CommandBuffer::CompletionCallback& callback) const { - FML_DCHECK(style_ == Style::kStroke); - using PS = PathPolylineComputeShader; - using SS = StrokeComputeShader; - - auto cubic_count = path.GetComponentCount(Path::ComponentType::kCubic); - auto quad_count = path.GetComponentCount(Path::ComponentType::kQuadratic) + - (cubic_count * 6); - auto line_count = - path.GetComponentCount(Path::ComponentType::kLinear) + (quad_count * 6); - if (cubic_count > kMaxCubicCount || quad_count > kMaxQuadCount || - line_count > kMaxLineCount) { - return Status::kTooManyComponents; - } - PS::Cubics cubics{.count = 0}; - PS::Quads quads{.count = 0}; - PS::Lines lines{.count = 0}; - PS::Components components{.count = 0}; - PS::Config config{.cubic_accuracy = cubic_accuracy_, - .quad_tolerance = quad_tolerance_}; - - path.EnumerateComponents( - [&lines, &components](size_t index, const LinearPathComponent& linear) { - ::memcpy(&lines.data[lines.count], &linear, - sizeof(LinearPathComponent)); - components.data[components.count++] = {lines.count++, 2}; - }, - [&quads, &components](size_t index, const QuadraticPathComponent& quad) { - ::memcpy(&quads.data[quads.count], &quad, - sizeof(QuadraticPathComponent)); - components.data[components.count++] = {quads.count++, 3}; - }, - [&cubics, &components](size_t index, const CubicPathComponent& cubic) { - ::memcpy(&cubics.data[cubics.count], &cubic, - sizeof(CubicPathComponent)); - components.data[components.count++] = {cubics.count++, 4}; - }, - [](size_t index, const ContourComponent& contour) {}); - - auto polyline_buffer = - CreateDeviceBuffer>(context, "Polyline"); - - auto cmd_buffer = context->CreateCommandBuffer(); - auto pass = cmd_buffer->CreateComputePass(); - FML_DCHECK(pass && pass->IsValid()); - - { - using PathPolylinePipelineBuilder = ComputePipelineBuilder; - auto pipeline_desc = - PathPolylinePipelineBuilder::MakeDefaultPipelineDescriptor(*context); - FML_DCHECK(pipeline_desc.has_value()); - auto compute_pipeline = - context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get(); - FML_DCHECK(compute_pipeline); - - pass->SetPipeline(compute_pipeline); - pass->SetCommandLabel("Generate Polyline"); - - PS::BindConfig(*pass, host_buffer.EmplaceUniform(config)); - PS::BindCubics(*pass, host_buffer.EmplaceStorageBuffer(cubics)); - PS::BindQuads(*pass, host_buffer.EmplaceStorageBuffer(quads)); - PS::BindLines(*pass, host_buffer.EmplaceStorageBuffer(lines)); - PS::BindComponents(*pass, host_buffer.EmplaceStorageBuffer(components)); - PS::BindPolyline(*pass, DeviceBuffer::AsBufferView(polyline_buffer)); - - if (!pass->Compute(ISize(line_count, 1)).ok()) { - return Status::kCommandInvalid; - } - } - - { - using StrokePipelineBuilder = ComputePipelineBuilder; - auto pipeline_desc = - StrokePipelineBuilder::MakeDefaultPipelineDescriptor(*context); - FML_DCHECK(pipeline_desc.has_value()); - auto compute_pipeline = - context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get(); - FML_DCHECK(compute_pipeline); - - pass->AddBufferMemoryBarrier(); - pass->SetPipeline(compute_pipeline); - pass->SetCommandLabel("Compute Stroke"); - - SS::Config config{ - .width = stroke_width_, - .cap = static_cast(stroke_cap_), - .join = static_cast(stroke_join_), - .miter_limit = miter_limit_, - }; - SS::BindConfig(*pass, host_buffer.EmplaceUniform(config)); - - SS::BindPolyline(*pass, DeviceBuffer::AsBufferView(polyline_buffer)); - SS::BindVertexBufferCount(*pass, std::move(vertex_buffer_count)); - SS::BindVertexBuffer(*pass, std::move(vertex_buffer)); - - if (!pass->Compute(ISize(line_count, 1)).ok()) { - return Status::kCommandInvalid; - } - } - - if (!pass->EncodeCommands()) { - return Status::kCommandInvalid; - } - - if (!context->GetCommandQueue()->Submit({cmd_buffer}, callback).ok()) { - return Status::kCommandInvalid; - } - - return Status::kOk; -} - -} // namespace impeller diff --git a/impeller/renderer/compute_tessellator.h b/impeller/renderer/compute_tessellator.h deleted file mode 100644 index a74c54ea29e6f..0000000000000 --- a/impeller/renderer/compute_tessellator.h +++ /dev/null @@ -1,89 +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. - -#ifndef FLUTTER_IMPELLER_RENDERER_COMPUTE_TESSELLATOR_H_ -#define FLUTTER_IMPELLER_RENDERER_COMPUTE_TESSELLATOR_H_ - -#include "impeller/core/buffer_view.h" -#include "impeller/geometry/path.h" -#include "impeller/renderer/command_buffer.h" -#include "impeller/renderer/context.h" - -namespace impeller { - -//------------------------------------------------------------------------------ -/// @brief A utility that generates triangles of the specified fill type -/// given a path. -/// -class ComputeTessellator { - public: - ComputeTessellator(); - - ~ComputeTessellator(); - - static constexpr size_t kMaxCubicCount = 512; - static constexpr size_t kMaxQuadCount = 2048; - static constexpr size_t kMaxLineCount = 4096; - static constexpr size_t kMaxComponentCount = - kMaxCubicCount + kMaxQuadCount + kMaxLineCount; - - enum class Status { - kCommandInvalid, - kTooManyComponents, - kOk, - }; - - enum class Style { - kStroke, - // TODO(dnfield): Implement kFill. - }; - - ComputeTessellator& SetStyle(Style value); - ComputeTessellator& SetStrokeWidth(Scalar value); - ComputeTessellator& SetStrokeJoin(Join value); - ComputeTessellator& SetStrokeCap(Cap value); - ComputeTessellator& SetMiterLimit(Scalar value); - ComputeTessellator& SetCubicAccuracy(Scalar value); - ComputeTessellator& SetQuadraticTolerance(Scalar value); - - //---------------------------------------------------------------------------- - /// @brief Generates triangles from the path. - /// If the data needs to be synchronized back to the CPU, e.g. - /// because one of the buffer views are host visible and will be - /// used without creating a blit pass to copy them back, the - /// callback is used to determine when the GPU calculation is - /// complete and its status. - /// On Metal, no additional synchronization is needed as long as - /// the buffers are not heap allocated, so no additional - /// synchronization mechanism is provided. - /// - /// @return A |Status| value indicating success or failure of the submission. - /// - // TODO(dnfield): Provide additional synchronization methods here for Vulkan - // and heap allocated buffers on Metal. - Status Tessellate( - const Path& path, - HostBuffer& host_buffer, - const std::shared_ptr& context, - BufferView vertex_buffer, - BufferView vertex_buffer_count, - const CommandBuffer::CompletionCallback& callback = nullptr) const; - - private: - Style style_ = Style::kStroke; - Scalar stroke_width_ = 1.0f; - Cap stroke_cap_ = Cap::kButt; - Join stroke_join_ = Join::kMiter; - Scalar miter_limit_ = 4.0f; - Scalar cubic_accuracy_ = .1f; - Scalar quad_tolerance_ = .1f; - - ComputeTessellator(const ComputeTessellator&) = delete; - - ComputeTessellator& operator=(const ComputeTessellator&) = delete; -}; - -} // namespace impeller - -#endif // FLUTTER_IMPELLER_RENDERER_COMPUTE_TESSELLATOR_H_ diff --git a/impeller/renderer/path_polyline.comp b/impeller/renderer/path_polyline.comp deleted file mode 100644 index 0804c8f12d827..0000000000000 --- a/impeller/renderer/path_polyline.comp +++ /dev/null @@ -1,170 +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. -#extension GL_KHR_shader_subgroup_arithmetic : enable - -layout(local_size_x = 256, local_size_y = 1) in; -layout(std430) buffer; - -#include - -layout(binding = 0) readonly buffer Cubics { - uint count; - CubicData data[]; -} -cubics; - -layout(binding = 1) buffer Quads { - uint count; - QuadData data[]; -} -quads; - -layout(binding = 2) buffer Lines { - uint count; - LineData data[]; -} -lines; - -layout(binding = 3) buffer Components { - uint count; - PathComponent data[]; -} -components; - -layout(binding = 4) buffer Polyline { - uint count; - vec2 data[]; -} -polyline; - -uniform Config { - float cubic_accuracy; - float quad_tolerance; -} -config; - -shared uvec2 cubic_ranges[512]; -shared uvec2 quad_ranges[512]; -shared uint scratch_count[512]; -shared uint scratch_sum[512]; - -uint ComputePosition(uint index) { - uint sum = scratch_sum[index]; - for (uint position = gl_SubgroupSize - 1; position < index; - position += gl_SubgroupSize) { - sum += scratch_sum[position] + scratch_count[position]; - } - return sum; -} - -void ProcessCubic(uint ident) { - CubicData cubic; - uint quad_count = 0; - if (ident < cubics.count) { - cubic = cubics.data[ident]; - quad_count = EstimateQuadraticCount(cubic, config.cubic_accuracy); - scratch_count[ident] = quad_count; - } - - barrier(); - - uint offset = 0; - if (quad_count > 0) { - scratch_sum[ident] = subgroupExclusiveAdd(scratch_count[ident]); - - offset = ComputePosition(ident) + quads.count; - } - barrier(); - if (quad_count > 0) { - atomicAdd(quads.count, quad_count); - - cubic_ranges[ident] = uvec2(offset, quad_count); - for (uint i = 0; i < quad_count; i++) { - quads.data[offset + i] = GenerateQuadraticFromCubic(cubic, i, quad_count); - } - } -} - -void ProcessQuad(uint ident) { - QuadData quad; - QuadDecomposition decomposition; - if (ident < quads.count) { - quad = quads.data[ident]; - decomposition = DecomposeQuad(quad, config.quad_tolerance); - scratch_count[ident] = decomposition.line_count; - } - - barrier(); - - uint offset = 0; - if (decomposition.line_count > 0) { - scratch_sum[ident] = subgroupExclusiveAdd(scratch_count[ident]); - offset = ComputePosition(ident) + lines.count; - } - barrier(); - - if (decomposition.line_count > 0) { - atomicAdd(lines.count, decomposition.line_count); - quad_ranges[ident] = uvec2(offset, decomposition.line_count); - - vec2 last_point = quad.p1; - for (uint i = 1; i < decomposition.line_count; i++) { - LineData line = - LineData(last_point, GenerateLineFromQuad(quad, i, decomposition)); - last_point = line.p2; - lines.data[offset + i - 1] = line; - } - lines.data[offset + decomposition.line_count - 1] = - LineData(last_point, quad.p2); - } -} - -void ProcessLine(uint ident) { - if (ident == 0) { - polyline.count = lines.count + 1; - } - - PathComponent component; - uvec2 range = uvec2(0, 0); - if (ident < components.count) { - component = components.data[ident]; - if (component.count == 4) { - // Determine location in quads - uvec2 quad_range = cubic_ranges[component.index]; - uvec2 end_range = quad_ranges[quad_range.x + quad_range.y - 1]; - range.x = quad_ranges[quad_range.x].x; - range.y = end_range.x + end_range.y - range.x; - } else if (component.count == 3) { - range = quad_ranges[component.index]; - } else if (component.count == 2) { - range = uvec2(component.index, 1); - } - - scratch_count[ident] = range.y; - } - barrier(); - - if (ident < components.count) { - scratch_sum[ident] = subgroupExclusiveAdd(scratch_count[ident]); - uint offset = ComputePosition(ident); - polyline.data[offset] = lines.data[range.x].p1; - for (uint i = 0; i < range.y; i++) { - polyline.data[offset + i + 1] = lines.data[range.x + i].p2; - } - } -} - -void main() { - uint ident = gl_GlobalInvocationID.x; - // Turn each cubic into quads. - ProcessCubic(ident); - barrier(); - - // Turn each quad into lines. - ProcessQuad(ident); - barrier(); - - // Copy lines to the output buffer. - ProcessLine(ident); -} diff --git a/impeller/renderer/stroke.comp b/impeller/renderer/stroke.comp deleted file mode 100644 index 5d9cf55fafa4b..0000000000000 --- a/impeller/renderer/stroke.comp +++ /dev/null @@ -1,60 +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. -#extension GL_KHR_shader_subgroup_arithmetic : enable - -layout(local_size_x = 256, local_size_y = 1) in; -layout(std430) buffer; - -layout(binding = 0) buffer Polyline { - uint count; - vec2 data[]; -} -polyline; - -layout(binding = 1) buffer VertexBuffer { - vec2 position[]; -} -vertex_buffer; - -layout(binding = 2) buffer VertexBufferCount { - uint count; -} -vertex_buffer_count; - -uniform Config { - float width; - uint cap; - uint join; - float miter_limit; -} -config; - -vec2 compute_offset(uint index) { - vec2 direction = normalize(polyline.data[index + 1] - polyline.data[index]); - return vec2(-direction.y, direction.x) * config.width * .5; -} - -void main() { - uint ident = gl_GlobalInvocationID.x; - if (ident >= polyline.count || ident == 0) { - // This is ok because there is no barrier() below. - return; - } - - atomicAdd(vertex_buffer_count.count, 4); - - uint index = ident - 1; - vec2 offset = compute_offset(index); - vertex_buffer.position[index * 4 + 0] = polyline.data[ident - 1] + offset; - vertex_buffer.position[index * 4 + 1] = polyline.data[ident - 1] - offset; - vertex_buffer.position[index * 4 + 2] = polyline.data[ident] + offset; - vertex_buffer.position[index * 4 + 3] = polyline.data[ident] - offset; - - // TODO(dnfield): Implement other cap/join mechanisms. - if (ident == polyline.count - 1) { - vertex_buffer.position[index * 4 + 4] = polyline.data[ident] + offset; - vertex_buffer.position[index * 4 + 5] = polyline.data[ident] - offset; - atomicAdd(vertex_buffer_count.count, 2); - } -} From d85e04a99017435f6fbbe627acd2ef2fb048a864 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 6 May 2024 13:46:04 -0700 Subject: [PATCH 2/2] update licenses. --- ci/licenses_golden/excluded_files | 1 - ci/licenses_golden/licenses_flutter | 8 -- impeller/tools/malioc.json | 125 ---------------------------- 3 files changed, 134 deletions(-) diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index 36c5b50ffc61a..a2d4783ea07a5 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -184,7 +184,6 @@ ../../../flutter/impeller/renderer/backend/vulkan/test ../../../flutter/impeller/renderer/blit_pass_unittests.cc ../../../flutter/impeller/renderer/capabilities_unittests.cc -../../../flutter/impeller/renderer/compute_subgroup_unittests.cc ../../../flutter/impeller/renderer/compute_unittests.cc ../../../flutter/impeller/renderer/device_buffer_unittests.cc ../../../flutter/impeller/renderer/pipeline_descriptor_unittests.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index eb2bad60a7a1c..90536fbdd422e 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -40777,11 +40777,8 @@ ORIGIN: ../../../flutter/impeller/renderer/compute_pipeline_builder.cc + ../../. ORIGIN: ../../../flutter/impeller/renderer/compute_pipeline_builder.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/compute_pipeline_descriptor.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/compute_pipeline_descriptor.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/renderer/compute_tessellator.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/renderer/compute_tessellator.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/context.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/context.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/renderer/path_polyline.comp + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/pipeline.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/pipeline.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/pipeline_builder.cc + ../../../flutter/LICENSE @@ -40809,7 +40806,6 @@ ORIGIN: ../../../flutter/impeller/renderer/shader_library.h + ../../../flutter/L ORIGIN: ../../../flutter/impeller/renderer/shader_stage_compatibility_checker.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/snapshot.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/snapshot.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/renderer/stroke.comp + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/surface.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/surface.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/texture_mipmap.cc + ../../../flutter/LICENSE @@ -43657,11 +43653,8 @@ FILE: ../../../flutter/impeller/renderer/compute_pipeline_builder.cc FILE: ../../../flutter/impeller/renderer/compute_pipeline_builder.h FILE: ../../../flutter/impeller/renderer/compute_pipeline_descriptor.cc FILE: ../../../flutter/impeller/renderer/compute_pipeline_descriptor.h -FILE: ../../../flutter/impeller/renderer/compute_tessellator.cc -FILE: ../../../flutter/impeller/renderer/compute_tessellator.h FILE: ../../../flutter/impeller/renderer/context.cc FILE: ../../../flutter/impeller/renderer/context.h -FILE: ../../../flutter/impeller/renderer/path_polyline.comp FILE: ../../../flutter/impeller/renderer/pipeline.cc FILE: ../../../flutter/impeller/renderer/pipeline.h FILE: ../../../flutter/impeller/renderer/pipeline_builder.cc @@ -43689,7 +43682,6 @@ FILE: ../../../flutter/impeller/renderer/shader_library.h FILE: ../../../flutter/impeller/renderer/shader_stage_compatibility_checker.h FILE: ../../../flutter/impeller/renderer/snapshot.cc FILE: ../../../flutter/impeller/renderer/snapshot.h -FILE: ../../../flutter/impeller/renderer/stroke.comp FILE: ../../../flutter/impeller/renderer/surface.cc FILE: ../../../flutter/impeller/renderer/surface.h FILE: ../../../flutter/impeller/renderer/texture_mipmap.cc diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index 856dc2c6a6625..35b83ea0ee66f 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -7622,68 +7622,6 @@ } } }, - "flutter/impeller/renderer/path_polyline.comp.vkspv": { - "Mali-G78": { - "core": "Mali-G78", - "filename": "flutter/impeller/renderer/path_polyline.comp.vkspv", - "has_uniform_computation": true, - "type": "Compute", - "variants": { - "Main": { - "fp16_arithmetic": 0, - "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.609375, - 0.0, - 0.609375, - 0.3125, - 4.0, - 0.0 - ], - "total_bound_pipelines": [ - "load_store" - ], - "total_cycles": [ - 5.9375, - 2.737499952316284, - 4.987500190734863, - 5.9375, - 37.20000076293945, - 0.0 - ] - }, - "shared_storage_used": 12288, - "stack_spill_bytes": 0, - "thread_occupancy": 50, - "uniform_registers_used": 32, - "work_registers_used": 51 - } - } - } - }, "flutter/impeller/renderer/prefix_sum_test.comp.vkspv": { "Mali-G78": { "core": "Mali-G78", @@ -7747,69 +7685,6 @@ } } }, - "flutter/impeller/renderer/stroke.comp.vkspv": { - "Mali-G78": { - "core": "Mali-G78", - "filename": "flutter/impeller/renderer/stroke.comp.vkspv", - "has_uniform_computation": true, - "type": "Compute", - "variants": { - "Main": { - "fp16_arithmetic": 0, - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - "load_store" - ], - "longest_path_cycles": [ - 0.3125, - 0.3125, - 0.1875, - 0.125, - 7.0, - 0.0 - ], - "pipelines": [ - "arith_total", - "arith_fma", - "arith_cvt", - "arith_sfu", - "load_store", - "texture" - ], - "shortest_path_bound_pipelines": [ - "arith_total", - "arith_cvt" - ], - "shortest_path_cycles": [ - 0.0625, - 0.0, - 0.0625, - 0.0, - 0.0, - 0.0 - ], - "total_bound_pipelines": [ - "load_store" - ], - "total_cycles": [ - 0.3125, - 0.3125, - 0.1875, - 0.125, - 7.0, - 0.0 - ] - }, - "shared_storage_used": 0, - "stack_spill_bytes": 0, - "thread_occupancy": 100, - "uniform_registers_used": 10, - "work_registers_used": 24 - } - } - } - }, "flutter/impeller/renderer/threadgroup_sizing_test.comp.vkspv": { "Mali-G78": { "core": "Mali-G78",