Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
[Impeller] delete points compute shader.
  • Loading branch information
jonahwilliams committed Apr 23, 2024
commit 45edbde599eb7bcdee526a02d27ad5f74b32a654
8 changes: 0 additions & 8 deletions impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2349,10 +2349,6 @@ TEST_P(AiksTest, DrawPaintTransformsBounds) {
}

TEST_P(AiksTest, CanDrawPoints) {
if (GetBackend() == PlaygroundBackend::kMetal) {
// https://github.com/flutter/flutter/issues/147184
GTEST_SKIP() << "Draw Points is currently broken on the metal m1 backend.";
}
std::vector<Point> points = {
{0, 0}, //
{100, 100}, //
Expand Down Expand Up @@ -2447,10 +2443,6 @@ TEST_P(AiksTest, DrawAtlasAdvancedAndTransform) {
}

TEST_P(AiksTest, CanDrawPointsWithTextureMap) {
if (GetBackend() == PlaygroundBackend::kMetal) {
// https://github.com/flutter/flutter/issues/147184
GTEST_SKIP() << "Draw Points is currently broken on the metal m1 backend.";
}
auto texture = CreateTextureForFixture("table_mountain_nx.png",
/*enable_mipmapping=*/true);

Expand Down
1 change: 0 additions & 1 deletion impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ impeller_shaders("modern_entity_shaders") {
"shaders/gradients/linear_gradient_ssbo_fill.frag",
"shaders/gradients/radial_gradient_ssbo_fill.frag",
"shaders/gradients/sweep_gradient_ssbo_fill.frag",
"shaders/geometry/points.comp",
]
}

Expand Down
6 changes: 0 additions & 6 deletions impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -450,12 +450,6 @@ ContentContext::ContentContext(
tiled_texture_external_pipelines_.CreateDefault(*context_, options);
}
#endif // IMPELLER_ENABLE_OPENGLES
if (context_->GetCapabilities()->SupportsCompute()) {
auto pipeline_desc =
PointsComputeShaderPipeline::MakeDefaultPipelineDescriptor(*context_);
point_field_compute_pipelines_ =
context_->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
}

is_valid_ = true;
InitializeCommonlyUsedShadersIfNeeded();
Expand Down
12 changes: 0 additions & 12 deletions impeller/entity/contents/content_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
#include "impeller/entity/linear_to_srgb_filter.frag.h"
#include "impeller/entity/morphology_filter.frag.h"
#include "impeller/entity/morphology_filter.vert.h"
#include "impeller/entity/points.comp.h"
#include "impeller/entity/porter_duff_blend.frag.h"
#include "impeller/entity/porter_duff_blend.vert.h"
#include "impeller/entity/radial_gradient_fill.frag.h"
Expand Down Expand Up @@ -256,9 +255,6 @@ using FramebufferBlendSoftLightPipeline =
using VerticesUberShader =
RenderPipelineHandle<VerticesUberVertexShader, VerticesUberFragmentShader>;

/// Geometry Pipelines
using PointsComputeShaderPipeline = ComputePipelineBuilder<PointsComputeShader>;

#ifdef IMPELLER_ENABLE_OPENGLES
using TiledTextureExternalPipeline =
RenderPipelineHandle<TextureUvFillVertexShader,
Expand Down Expand Up @@ -719,12 +715,6 @@ class ContentContext {
return GetPipeline(vertices_uber_shader_, opts);
}

std::shared_ptr<Pipeline<ComputePipelineDescriptor>> GetPointComputePipeline()
const {
FML_DCHECK(GetDeviceCapabilities().SupportsCompute());
return point_field_compute_pipelines_;
}

std::shared_ptr<Context> GetContext() const;

const Capabilities& GetDeviceCapabilities() const;
Expand Down Expand Up @@ -987,8 +977,6 @@ class ContentContext {
mutable Variants<FramebufferBlendSoftLightPipeline>
framebuffer_blend_softlight_pipelines_;
mutable Variants<VerticesUberShader> vertices_uber_shader_;
mutable std::shared_ptr<Pipeline<ComputePipelineDescriptor>>
point_field_compute_pipelines_;

template <class TypedPipeline>
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
Expand Down
226 changes: 66 additions & 160 deletions impeller/entity/geometry/point_field_geometry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

#include "impeller/entity/geometry/point_field_geometry.h"

#include "impeller/geometry/color.h"
#include "impeller/core/vertex_buffer.h"
#include "impeller/entity/geometry/geometry.h"
#include "impeller/renderer/command_buffer.h"

namespace impeller {
Expand All @@ -18,40 +19,19 @@ GeometryResult PointFieldGeometry::GetPositionBuffer(
const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
if (renderer.GetDeviceCapabilities().SupportsCompute()) {
return GetPositionBufferGPU(renderer, entity, pass);
}
auto vtx_builder = GetPositionBufferCPU(renderer, entity, pass);
if (!vtx_builder.has_value()) {
return {};
}

auto& host_buffer = renderer.GetTransientsBuffer();
return {
.type = PrimitiveType::kTriangleStrip,
.vertex_buffer = vtx_builder->CreateVertexBuffer(host_buffer),
.transform = entity.GetShaderTransform(pass),
};
}

std::optional<VertexBufferBuilder<SolidFillVertexShader::PerVertexData>>
PointFieldGeometry::GetPositionBufferCPU(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
if (radius_ < 0.0) {
return std::nullopt;
return {};
}
auto transform = entity.GetTransform();
auto determinant = transform.GetDeterminant();
Matrix transform = entity.GetTransform();
Scalar determinant = transform.GetDeterminant();
if (determinant == 0) {
return std::nullopt;
return {};
}

Scalar min_size = 1.0f / sqrt(std::abs(determinant));
Scalar radius = std::max(radius_, min_size);

VertexBufferBuilder<SolidFillVertexShader::PerVertexData> vtx_builder;

HostBuffer& host_buffer = renderer.GetTransientsBuffer();
if (round_) {
// Get triangulation relative to {0, 0} so we can translate it to each
// point in turn.
Expand All @@ -65,143 +45,69 @@ PointFieldGeometry::GetPositionBufferCPU(const ContentContext& renderer,
});
FML_DCHECK(circle_vertices.size() == generator.GetVertexCount());

vtx_builder.Reserve((circle_vertices.size() + 2) * points_.size() - 2);
for (auto& center : points_) {
if (vtx_builder.HasVertices()) {
vtx_builder.AppendVertex(vtx_builder.Last());
vtx_builder.AppendVertex({center + circle_vertices[0]});
}

for (auto& vertex : circle_vertices) {
vtx_builder.AppendVertex({center + vertex});
}
}
} else {
vtx_builder.Reserve(6 * points_.size() - 2);
for (auto& point : points_) {
auto first = Point(point.x - radius, point.y - radius);

if (vtx_builder.HasVertices()) {
vtx_builder.AppendVertex(vtx_builder.Last());
vtx_builder.AppendVertex({first});
}

// Z pattern from UL -> UR -> LL -> LR
vtx_builder.AppendVertex({first});
vtx_builder.AppendVertex({{point.x + radius, point.y - radius}});
vtx_builder.AppendVertex({{point.x - radius, point.y + radius}});
vtx_builder.AppendVertex({{point.x + radius, point.y + radius}});
}
}

return vtx_builder;
}

GeometryResult PointFieldGeometry::GetPositionBufferGPU(
const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
FML_DCHECK(renderer.GetDeviceCapabilities().SupportsCompute());
if (radius_ < 0.0) {
return {};
}
Scalar determinant = entity.GetTransform().GetDeterminant();
if (determinant == 0) {
return {};
}

Scalar min_size = 1.0f / sqrt(std::abs(determinant));
Scalar radius = std::max(radius_, min_size);

size_t vertices_per_geom = ComputeCircleDivisions(
entity.GetTransform().GetMaxBasisLength() * radius, round_);

size_t points_per_circle = 3 + (vertices_per_geom - 3) * 3;
size_t total = points_per_circle * points_.size();

std::shared_ptr<CommandBuffer> cmd_buffer =
renderer.GetContext()->CreateCommandBuffer();
std::shared_ptr<ComputePass> compute_pass = cmd_buffer->CreateComputePass();
HostBuffer& host_buffer = renderer.GetTransientsBuffer();

BufferView points_data =
host_buffer.Emplace(points_.data(), points_.size() * sizeof(Point),
DefaultUniformAlignment());

BufferView geometry_buffer =
host_buffer.Emplace(nullptr, total * sizeof(Point),
std::max(DefaultUniformAlignment(), alignof(Point)));

BufferView output;
{
using PS = PointsComputeShader;

compute_pass->SetPipeline(renderer.GetPointComputePipeline());
compute_pass->SetCommandLabel("Points Geometry");

PS::FrameInfo frame_info;
frame_info.count = points_.size();
frame_info.radius = round_ ? radius : radius * kSqrt2;
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;

PS::BindFrameInfo(*compute_pass, host_buffer.EmplaceUniform(frame_info));
PS::BindGeometryData(*compute_pass, geometry_buffer);
PS::BindPointData(*compute_pass, points_data);

if (!compute_pass->Compute(ISize(total, 1)).ok()) {
return {};
}
output = geometry_buffer;
}

if (!compute_pass->EncodeCommands()) {
return {};
}
if (!renderer.GetContext()
->GetCommandQueue()
->Submit({std::move(cmd_buffer)})
.ok()) {
return {};
}

return {
.type = PrimitiveType::kTriangle,
.vertex_buffer = {.vertex_buffer = std::move(output),
.vertex_count = total,
.index_type = IndexType::kNone},
size_t vertex_count = ((circle_vertices.size() + 2) * points_.size() - 2);
BufferView vertex_data =
host_buffer.Emplace(vertex_count, alignof(Point), [&](uint8_t* data) {
Point* output = reinterpret_cast<Point*>(data);
size_t offset = 0;

for (auto& vertex : circle_vertices) {
output[offset++] = vertex + points_[0];
}

for (auto i = 1u; i < vertex_count; i++) {
output[offset++] = output[offset];
output[offset++] = circle_vertices[0] + points_[i];
for (auto& vertex : circle_vertices) {
output[offset++] = vertex + points_[i];
}
}
});

return GeometryResult{
.type = PrimitiveType::kTriangleStrip,
.vertex_buffer = VertexBuffer{.vertex_buffer = std::move(vertex_data),
.index_buffer = {},
.vertex_count = vertex_count,
.index_type = IndexType::kNone},
.transform = entity.GetShaderTransform(pass),
};
}

size_t vertex_count = 6 * points_.size() - 2;
BufferView vertex_data =
host_buffer.Emplace(vertex_count, alignof(Point), [&](uint8_t* data) {
Point* output = reinterpret_cast<Point*>(data);
size_t offset = 0;
bool has_vertices = false;

for (auto& point : points_) {
Point first = Point(point.x - radius, point.y - radius);

if (has_vertices) {
output[offset++] = output[offset];
output[offset++] = first;
}

// Z pattern from UL -> UR -> LL -> LR
output[offset++] = first;
output[offset++] = Point{point.x + radius, point.y - radius};
output[offset++] = Point{point.x - radius, point.y + radius};
output[offset++] = Point{point.x + radius, point.y + radius};
has_vertices = true;
}
});

return GeometryResult{
.type = PrimitiveType::kTriangleStrip,
.vertex_buffer = VertexBuffer{.vertex_buffer = std::move(vertex_data),
.index_buffer = {},
.vertex_count = vertex_count,
.index_type = IndexType::kNone},
.transform = entity.GetShaderTransform(pass),
};
}

/// @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) {
return 4;
}

// 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 < 12.0) {
return 24;
}
if (scaled_radius < 22.0) {
return 34;
}
return std::min(scaled_radius, 140.0f);
}

// |Geometry|
GeometryVertexType PointFieldGeometry::GetVertexType() const {
return GeometryVertexType::kPosition;
Expand Down
9 changes: 0 additions & 9 deletions impeller/entity/geometry/point_field_geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,6 @@ class PointFieldGeometry final : public Geometry {
// |Geometry|
std::optional<Rect> GetCoverage(const Matrix& transform) const override;

GeometryResult GetPositionBufferGPU(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const;

std::optional<VertexBufferBuilder<SolidFillVertexShader::PerVertexData>>
GetPositionBufferCPU(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const;

std::vector<Point> points_;
Scalar radius_;
bool round_;
Expand Down
Loading