Skip to content

Commit abf3ef7

Browse files
author
Jonah Williams
authored
[CP][Impeller] Use multiple command buffers to submit blur encode. (flutter#54942)
flutter/flutter#154564
1 parent 4b76ac4 commit abf3ef7

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

impeller/entity/contents/filters/gaussian_blur_filter_contents.cc

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -669,9 +669,15 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
669669
return result;
670670
}
671671

672-
std::shared_ptr<CommandBuffer> command_buffer =
672+
// Note: The code below uses three different command buffers when it would be
673+
// possible to combine the operations into a single buffer. From testing and
674+
// user bug reports (see https://github.com/flutter/flutter/issues/154046 ),
675+
// this sometimes causes deviceLost errors on older Adreno devices. Breaking
676+
// the work up into three different command buffers seems to prevent this
677+
// crash.
678+
std::shared_ptr<CommandBuffer> command_buffer_1 =
673679
renderer.GetContext()->CreateCommandBuffer();
674-
if (!command_buffer) {
680+
if (!command_buffer_1) {
675681
return std::nullopt;
676682
}
677683

@@ -680,7 +686,7 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
680686
source_expanded_coverage_hint, inputs[0], snapshot_entity);
681687

682688
fml::StatusOr<RenderTarget> pass1_out = MakeDownsampleSubpass(
683-
renderer, command_buffer, input_snapshot->texture,
689+
renderer, command_buffer_1, input_snapshot->texture,
684690
input_snapshot->sampler_descriptor, downsample_pass_args, tile_mode_);
685691

686692
if (!pass1_out.ok()) {
@@ -692,8 +698,14 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
692698

693699
Quad blur_uvs = {Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)};
694700

701+
std::shared_ptr<CommandBuffer> command_buffer_2 =
702+
renderer.GetContext()->CreateCommandBuffer();
703+
if (!command_buffer_2) {
704+
return std::nullopt;
705+
}
706+
695707
fml::StatusOr<RenderTarget> pass2_out = MakeBlurSubpass(
696-
renderer, command_buffer, /*input_pass=*/pass1_out.value(),
708+
renderer, command_buffer_2, /*input_pass=*/pass1_out.value(),
697709
input_snapshot->sampler_descriptor, tile_mode_,
698710
BlurParameters{
699711
.blur_uv_offset = Point(0.0, pass1_pixel_size.y),
@@ -709,14 +721,20 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
709721
return std::nullopt;
710722
}
711723

724+
std::shared_ptr<CommandBuffer> command_buffer_3 =
725+
renderer.GetContext()->CreateCommandBuffer();
726+
if (!command_buffer_3) {
727+
return std::nullopt;
728+
}
729+
712730
// Only ping pong if the first pass actually created a render target.
713731
auto pass3_destination = pass2_out.value().GetRenderTargetTexture() !=
714732
pass1_out.value().GetRenderTargetTexture()
715733
? std::optional<RenderTarget>(pass1_out.value())
716734
: std::optional<RenderTarget>(std::nullopt);
717735

718736
fml::StatusOr<RenderTarget> pass3_out = MakeBlurSubpass(
719-
renderer, command_buffer, /*input_pass=*/pass2_out.value(),
737+
renderer, command_buffer_3, /*input_pass=*/pass2_out.value(),
720738
input_snapshot->sampler_descriptor, tile_mode_,
721739
BlurParameters{
722740
.blur_uv_offset = Point(pass1_pixel_size.x, 0.0),
@@ -734,7 +752,8 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
734752

735753
if (!renderer.GetContext()
736754
->GetCommandQueue()
737-
->Submit(/*buffers=*/{command_buffer})
755+
->Submit(/*buffers=*/{command_buffer_1, command_buffer_2,
756+
command_buffer_3})
738757
.ok()) {
739758
return std::nullopt;
740759
}

0 commit comments

Comments
 (0)