Skip to content

Commit 5f0b94f

Browse files
[Impeller] Return an empty contents in Paint::CreateContents if a runtime effect sampler is invalid (#165165)
Callers of Paint::CreateContents expect that the result is not null. See flutter/flutter#165119
1 parent 25a0d9a commit 5f0b94f

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

engine/src/flutter/impeller/display_list/aiks_dl_runtime_effect_unittests.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,5 +108,33 @@ TEST_P(AiksTest, CanRenderRuntimeEffectFilter) {
108108
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
109109
}
110110

111+
TEST_P(AiksTest, RuntimeEffectWithInvalidSamplerDoesNotCrash) {
112+
ScopedValidationDisable disable_validation;
113+
114+
// Create a sampler that is not usable as an input to the runtime effect.
115+
std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
116+
flutter::DlColor::kRed()};
117+
const float stops[2] = {0.0, 1.0};
118+
auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
119+
2, colors.data(), stops,
120+
flutter::DlTileMode::kClamp);
121+
std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
122+
linear,
123+
};
124+
125+
auto uniform_data = std::make_shared<std::vector<uint8_t>>();
126+
uniform_data->resize(sizeof(Vector2));
127+
128+
DlPaint paint;
129+
paint.setColorSource(
130+
MakeRuntimeEffect(this, "runtime_stage_filter_example.frag.iplr",
131+
uniform_data, sampler_inputs));
132+
133+
DisplayListBuilder builder;
134+
builder.DrawPaint(paint);
135+
136+
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
137+
}
138+
111139
} // namespace testing
112140
} // namespace impeller

engine/src/flutter/impeller/display_list/paint.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,17 @@ std::shared_ptr<ColorSourceContents> Paint::CreateContents() const {
218218

219219
for (auto& sampler : samplers) {
220220
if (sampler == nullptr) {
221-
return nullptr;
221+
VALIDATION_LOG << "Runtime effect sampler is null";
222+
auto contents = std::make_shared<SolidColorContents>();
223+
contents->SetColor(Color::BlackTransparent());
224+
return contents;
222225
}
223226
auto* image = sampler->asImage();
224227
if (!sampler->asImage()) {
225-
return nullptr;
228+
VALIDATION_LOG << "Runtime effect sampler is not an image";
229+
auto contents = std::make_shared<SolidColorContents>();
230+
contents->SetColor(Color::BlackTransparent());
231+
return contents;
226232
}
227233
FML_DCHECK(image->image()->impeller_texture());
228234
texture_inputs.push_back({

engine/src/flutter/testing/impeller_golden_tests_output.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,9 @@ impeller_Play_AiksTest_ReleasesTextureOnTeardown_Vulkan.png
877877
impeller_Play_AiksTest_RotateColorFilteredPath_Metal.png
878878
impeller_Play_AiksTest_RotateColorFilteredPath_OpenGLES.png
879879
impeller_Play_AiksTest_RotateColorFilteredPath_Vulkan.png
880+
impeller_Play_AiksTest_RuntimeEffectWithInvalidSamplerDoesNotCrash_Metal.png
881+
impeller_Play_AiksTest_RuntimeEffectWithInvalidSamplerDoesNotCrash_OpenGLES.png
882+
impeller_Play_AiksTest_RuntimeEffectWithInvalidSamplerDoesNotCrash_Vulkan.png
880883
impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_Metal.png
881884
impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_OpenGLES.png
882885
impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_Vulkan.png

0 commit comments

Comments
 (0)