Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Impeller] generate stroke vertices into point arena. #56390

Merged
merged 7 commits into from
Nov 6, 2024

Conversation

jonahwilliams
Copy link
Member

@jonahwilliams jonahwilliams commented Nov 5, 2024

Heap allocation is extremely expensive on Android.

We can speed up the stroke tessellation by allocation a large arena and using that to write vertices. If the vertices would overflow, we switch to a dynamically allocated vector.

@jonahwilliams jonahwilliams marked this pull request as ready for review November 6, 2024 02:13
@@ -347,17 +350,18 @@ void CreateRoundCap(VertexWriter& vtx_builder,
vtx = position - orientation;
vtx_builder.AppendVertex(vtx);

arc.ToLinearPathComponents(scale, [&vtx_builder, &vtx, forward_normal,
position](const Point& point) {
Scalar line_count = std::ceilf(ComputeCubicSubdivisions(scale, arc));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From profiling, calling ToLinearPathComponents with a closure triggers a heap allocation on Android.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bummer, we could get away with it by eliminating all captures and passing in a pointer to something on the stack. This isn't a request to make that change, but I think it's better to keep the abstraction since it's used in multiple locations.

std::tuple<Foo, Bar, Baz> info = {foo, bar, baz};
arc.ToLinearPathComponents<decltype(info)>(
  scale,
  info, 
  [](const Point"& point, const decltype(info)& info) {
    auto vtx = info.position + point;
    //...
  });

vtx.position = position + (-point * direction).Reflect(middle_normal);
vtx_builder.AppendVertex(vtx.position);
});
CubicPathComponent arc(start_offset, start_handle, middle_handle, middle);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here,

From profiling, calling ToLinearPathComponents with a closure triggers a heap allocation on Android.


namespace {

template <typename VertexWriter>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed template code as its unused, we only have a single implementation.

@flutter-dashboard

This comment was marked as outdated.

@jonahwilliams jonahwilliams changed the title [Impeller] generate vertices into point arena. [Impeller] generate stroke vertices into point arena. Nov 6, 2024
Copy link
Member

@gaaclarke gaaclarke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, code looks good, I just have some nits on documentation and a suggestion on how to keep the abstraction we already had (up to you if you want to do that though).

Path path = builder.TakePath();
auto geom = Geometry::MakeStrokePath(path, /*stroke_width=*/10);

ContentContext content_context(GetContext(), nullptr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ContentContext content_context(GetContext(), nullptr);
ContentContext content_context(GetContext(), /*typographer_context=*/nullptr);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

content_context.GetContext()->GetResourceAllocator());

auto render_target =
allocator.CreateOffscreen(*content_context.GetContext(), {10, 10}, 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
allocator.CreateOffscreen(*content_context.GetContext(), {10, 10}, 1);
allocator.CreateOffscreen(*content_context.GetContext(), /*size=*/{10, 10}, /*mip_count=*/1);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 2398 to 2403
EXPECT_NE(*(written_data + kPointArenaSize - 2), Point(0, 0));
EXPECT_NE(*(written_data + kPointArenaSize - 1), Point(0, 0));
EXPECT_NE(*(written_data + kPointArenaSize), Point(0, 0));
EXPECT_NE(*(written_data + kPointArenaSize + 1), Point(0, 0));
EXPECT_NE(*(written_data + kPointArenaSize + 2), Point(0, 0));
EXPECT_NE(*(written_data + kPointArenaSize + 3), Point(0, 0));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we switch these to EXPECT_EQ assertions? Not being Point(0,0) leaves a lot of possibilities.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is stroke tessellation the generated points are floating point values like 43.22132 ...

I could do a CLOSE_TO or something like that though. As long as they are in the ballpark

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}
}

size_t GetUsedSize() const { return offset_; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth documenting what this is supposed to return in a docstring since it's up to the client of this class to do the correct math with this and the oversized buffer's size.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, we could probably change this to just return offset_ + oversized_buffer_.size() to avoid the weirdness.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need both numbers to split up the memcp correctly

class PositionWriter {
public:
explicit PositionWriter(std::vector<Point>& points)
: points_(points), oversized_(0) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
: points_(points), oversized_(0) {}
: points_(points), oversized_() {}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

class PositionWriter {
public:
explicit PositionWriter(std::vector<Point>& points)
: points_(points), oversized_(0) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
: points_(points), oversized_(0) {}
: points_(points), oversized_(0) {
FML_DCHECK(points.size() >= kPointArenaSize);
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -347,17 +350,18 @@ void CreateRoundCap(VertexWriter& vtx_builder,
vtx = position - orientation;
vtx_builder.AppendVertex(vtx);

arc.ToLinearPathComponents(scale, [&vtx_builder, &vtx, forward_normal,
position](const Point& point) {
Scalar line_count = std::ceilf(ComputeCubicSubdivisions(scale, arc));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bummer, we could get away with it by eliminating all captures and passing in a pointer to something on the stack. This isn't a request to make that change, but I think it's better to keep the abstraction since it's used in multiple locations.

std::tuple<Foo, Bar, Baz> info = {foo, bar, baz};
arc.ToLinearPathComponents<decltype(info)>(
  scale,
  info, 
  [](const Point"& point, const decltype(info)& info) {
    auto vtx = info.position + point;
    //...
  });

.transform = entity.GetShaderTransform(pass),
.mode = GeometryResult::Mode::kPreventOverdraw};
}
FML_LOG(ERROR) << "Oversized";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stray log? It's worth keeping a comment here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

const std::vector<Point>& oversized_data =
position_writer.GetOveriszedBuffer();
BufferView buffer_view = host_buffer.Emplace(
nullptr,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
nullptr,
/*buffer=*/nullptr,

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Member

@gaaclarke gaaclarke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks!

@jonahwilliams jonahwilliams added the autosubmit Merge PR when tree becomes green via auto submit App label Nov 6, 2024
@auto-submit auto-submit bot merged commit 00c22da into flutter:main Nov 6, 2024
30 checks passed
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 6, 2024
auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Nov 6, 2024
…158295)

flutter/engine@58ac1da...b36ca33

2024-11-06 [email protected] [skwasm] Fix empty backdrop drawing. (flutter/engine#56385)
2024-11-06 [email protected] [Impeller] generate stroke vertices into point arena. (flutter/engine#56390)
2024-11-06 [email protected] [Impeller] Do not capture the temporary ImpellerMapping struct pointer when storing release callbacks in libImpeller (flutter/engine#56411)
2024-11-06 [email protected] Roll ICU from 9408c6fd4a39 to 4239b1559d11 (2 revisions) (flutter/engine#56407)
2024-11-06 [email protected] iOS,macOS: Add Obj-C cflags to all Obj-C targets (flutter/engine#56386)
2024-11-06 [email protected] Roll Skia from afaed8923682 to cf33c4e96e81 (5 revisions) (flutter/engine#56408)
2024-11-06 [email protected] Manual roll Dart SDK from 1c1d0420539f to d456f613465a (6 revisions) (flutter/engine#56406)
2024-11-06 [email protected] [Impeller] Avoid errors due to triangle fans usage on Molten. (flutter/engine#56321)
2024-11-06 [email protected] Roll Skia from b4df8dda7ffc to afaed8923682 (14 revisions) (flutter/engine#56404)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autosubmit Merge PR when tree becomes green via auto submit App e: impeller
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants