Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit f48ecf5

Browse files
[Impeller] Use multiple command buffers for blur submission. (#54846)
Fixes flutter/flutter#154046 Use three different command buffers when it would be possible to combine the operations into a single buffer. From testing and user bug reports (see flutter/flutter#154046 ), this sometimes causes deviceLost errors on older Adreno devices. Breaking the work up into three different command buffers seems to prevent this crash. I suspect this is due to some internal timeouts we may be hitting in the adreno driver.
1 parent e92ecf2 commit f48ecf5

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
@@ -727,9 +727,15 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
727727
return result;
728728
}
729729

730-
std::shared_ptr<CommandBuffer> command_buffer =
730+
// Note: The code below uses three different command buffers when it would be
731+
// possible to combine the operations into a single buffer. From testing and
732+
// user bug reports (see https://github.com/flutter/flutter/issues/154046 ),
733+
// this sometimes causes deviceLost errors on older Adreno devices. Breaking
734+
// the work up into three different command buffers seems to prevent this
735+
// crash.
736+
std::shared_ptr<CommandBuffer> command_buffer_1 =
731737
renderer.GetContext()->CreateCommandBuffer();
732-
if (!command_buffer) {
738+
if (!command_buffer_1) {
733739
return std::nullopt;
734740
}
735741

@@ -738,7 +744,7 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
738744
source_expanded_coverage_hint, inputs[0], snapshot_entity);
739745

740746
fml::StatusOr<RenderTarget> pass1_out = MakeDownsampleSubpass(
741-
renderer, command_buffer, input_snapshot->texture,
747+
renderer, command_buffer_1, input_snapshot->texture,
742748
input_snapshot->sampler_descriptor, downsample_pass_args, tile_mode_);
743749

744750
if (!pass1_out.ok()) {
@@ -750,8 +756,14 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
750756

751757
Quad blur_uvs = {Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)};
752758

759+
std::shared_ptr<CommandBuffer> command_buffer_2 =
760+
renderer.GetContext()->CreateCommandBuffer();
761+
if (!command_buffer_2) {
762+
return std::nullopt;
763+
}
764+
753765
fml::StatusOr<RenderTarget> pass2_out = MakeBlurSubpass(
754-
renderer, command_buffer, /*input_pass=*/pass1_out.value(),
766+
renderer, command_buffer_2, /*input_pass=*/pass1_out.value(),
755767
input_snapshot->sampler_descriptor, tile_mode_,
756768
BlurParameters{
757769
.blur_uv_offset = Point(0.0, pass1_pixel_size.y),
@@ -767,14 +779,20 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
767779
return std::nullopt;
768780
}
769781

782+
std::shared_ptr<CommandBuffer> command_buffer_3 =
783+
renderer.GetContext()->CreateCommandBuffer();
784+
if (!command_buffer_3) {
785+
return std::nullopt;
786+
}
787+
770788
// Only ping pong if the first pass actually created a render target.
771789
auto pass3_destination = pass2_out.value().GetRenderTargetTexture() !=
772790
pass1_out.value().GetRenderTargetTexture()
773791
? std::optional<RenderTarget>(pass1_out.value())
774792
: std::optional<RenderTarget>(std::nullopt);
775793

776794
fml::StatusOr<RenderTarget> pass3_out = MakeBlurSubpass(
777-
renderer, command_buffer, /*input_pass=*/pass2_out.value(),
795+
renderer, command_buffer_3, /*input_pass=*/pass2_out.value(),
778796
input_snapshot->sampler_descriptor, tile_mode_,
779797
BlurParameters{
780798
.blur_uv_offset = Point(pass1_pixel_size.x, 0.0),
@@ -792,7 +810,8 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
792810

793811
if (!renderer.GetContext()
794812
->GetCommandQueue()
795-
->Submit(/*buffers=*/{command_buffer})
813+
->Submit(/*buffers=*/{command_buffer_1, command_buffer_2,
814+
command_buffer_3})
796815
.ok()) {
797816
return std::nullopt;
798817
}

0 commit comments

Comments
 (0)