Skip to content

[impeller] crash in save layer when contents scaled by zero #177603

@gaaclarke

Description

@gaaclarke

description

The following test causes an FML_DCHECK to fail. Looks like this wasn't supposed to happen, but it can with zero scales.

seen in

542705c

reproduction

TEST_P(AiksTest, CrashInSaveLayer) {
  Scalar xoffset = 50;
  Scalar yoffset = 50;
  Scalar xscale = 0.0; // <-- This causes the crash.
  Scalar yscale = 0.7;
  Scalar sigma = 10.0;

  auto callback = [&]() -> sk_sp<DisplayList> {
    if (AiksTest::ImGuiBegin("Controls", nullptr,
                             ImGuiWindowFlags_AlwaysAutoResize)) {
      ImGui::SliderFloat("xscale", &xscale, 0, 1);
      ImGui::End();
    }
    DisplayListBuilder builder;

    auto blur_filter =
        DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);

    builder.Translate(xoffset, yoffset);
    builder.Scale(xscale, yscale);

    DlPaint paint;
    auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
    builder.DrawImage(image, DlPoint(100.0, 100.0),
                      DlImageSampling::kNearestNeighbor, &paint);

    DlPaint save_paint;
    save_paint.setBlendMode(DlBlendMode::kSrc);
    builder.SaveLayer(std::nullopt, &save_paint, blur_filter.get());
    builder.Restore();

    return builder.Build();
  };

  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

stacktrace

libsystem_kernel.dylib!__pthread_kill (Unknown Source:0)
libsystem_pthread.dylib!pthread_kill (Unknown Source:0)
libsystem_c.dylib!abort (Unknown Source:0)
impeller_unittests!fml::KillProcess() (/Users/aaclarke/dev/flutter/engine/src/flutter/fml/logging.cc:221)
impeller_unittests!fml::LogMessage::~LogMessage() (/Users/aaclarke/dev/flutter/engine/src/flutter/fml/logging.cc:208)
impeller_unittests!fml::LogMessage::~LogMessage() (/Users/aaclarke/dev/flutter/engine/src/flutter/fml/logging.cc:133)
impeller_unittests!flutter::DisplayListBuilder::saveLayer(impeller::TRect<float> const&, flutter::SaveLayerOptions, flutter::DlImageFilter const*, std::_fl::optional<long long>) (/Users/aaclarke/dev/flutter/engine/src/flutter/display_list/dl_builder.cc:468)
impeller_unittests!flutter::DisplayListBuilder::SaveLayer(std::_fl::optional<impeller::TRect<float>> const&, flutter::DlPaint const*, flutter::DlImageFilter const*, std::_fl::optional<long long>) (/Users/aaclarke/dev/flutter/engine/src/flutter/display_list/dl_builder.cc:560)
impeller_unittests!impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0::operator()() const (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/display_list/aiks_dl_runtime_effect_unittests.cc:308)
impeller_unittests!decltype(std::declval<impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0&>()()) std::_fl::__invoke[abi:nn210000]<impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0&>(impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0&) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__type_traits/invoke.h:179)
impeller_unittests!sk_sp<flutter::DisplayList> std::_fl::__invoke_void_return_wrapper<sk_sp<flutter::DisplayList>, false>::__call[abi:nn210000]<impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0&>(impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0&) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__type_traits/invoke.h:243)
impeller_unittests!sk_sp<flutter::DisplayList> std::_fl::__invoke_r[abi:nn210000]<sk_sp<flutter::DisplayList>, impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0&>(impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0&) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__type_traits/invoke.h:273)
impeller_unittests!std::_fl::__function::__alloc_func<impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0, std::_fl::allocator<impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0>, sk_sp<flutter::DisplayList> ()>::operator()[abi:nn210000]() (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__functional/function.h:167)
impeller_unittests!std::_fl::__function::__func<impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0, std::_fl::allocator<impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody()::$_0>, sk_sp<flutter::DisplayList> ()>::operator()() (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__functional/function.h:319)
impeller_unittests!std::_fl::__function::__value_func<sk_sp<flutter::DisplayList> ()>::operator()[abi:nn210000]() const (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__functional/function.h:436)
impeller_unittests!std::_fl::function<sk_sp<flutter::DisplayList> ()>::operator()() const (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__functional/function.h:995)
impeller_unittests!impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0::operator()(impeller::RenderTarget&) const (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/display_list/aiks_playground.cc:55)
impeller_unittests!decltype(std::declval<impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0&>()(std::declval<impeller::RenderTarget&>())) std::_fl::__invoke[abi:nn210000]<impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0&, impeller::RenderTarget&>(impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0&, impeller::RenderTarget&) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__type_traits/invoke.h:179)
impeller_unittests!bool std::_fl::__invoke_void_return_wrapper<bool, false>::__call[abi:nn210000]<impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0&, impeller::RenderTarget&>(impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0&, impeller::RenderTarget&) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__type_traits/invoke.h:243)
impeller_unittests!bool std::_fl::__invoke_r[abi:nn210000]<bool, impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0&, impeller::RenderTarget&>(impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0&, impeller::RenderTarget&) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__type_traits/invoke.h:273)
impeller_unittests!std::_fl::__function::__alloc_func<impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0, std::_fl::allocator<impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0>, bool (impeller::RenderTarget&)>::operator()[abi:nn210000](impeller::RenderTarget&) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__functional/function.h:167)
impeller_unittests!std::_fl::__function::__func<impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0, std::_fl::allocator<impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&)::$_0>, bool (impeller::RenderTarget&)>::operator()(impeller::RenderTarget&) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__functional/function.h:319)
impeller_unittests!std::_fl::__function::__value_func<bool (impeller::RenderTarget&)>::operator()[abi:nn210000](impeller::RenderTarget&) const (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__functional/function.h:436)
impeller_unittests!std::_fl::function<bool (impeller::RenderTarget&)>::operator()(impeller::RenderTarget&) const (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__functional/function.h:995)
impeller_unittests!impeller::Playground::OpenPlaygroundHere(std::_fl::function<bool (impeller::RenderTarget&)> const&) (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/playground/playground.cc:275)
impeller_unittests!impeller::AiksPlayground::OpenPlaygroundHere(std::_fl::function<sk_sp<flutter::DisplayList> ()> const&) (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/display_list/aiks_playground.cc:50)
impeller_unittests!impeller::testing::AiksTest_CrashInSaveLayer_Test::TestBody() (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/display_list/aiks_dl_runtime_effect_unittests.cc:314)
impeller_unittests!void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/googletest/googletest/src/gtest.cc:2613)
impeller_unittests!void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/googletest/googletest/src/gtest.cc:2668)
impeller_unittests!testing::Test::Run() (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/googletest/googletest/src/gtest.cc:2688)
impeller_unittests!testing::TestInfo::Run() (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/googletest/googletest/src/gtest.cc:2837)
impeller_unittests!testing::TestSuite::Run() (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/googletest/googletest/src/gtest.cc:3016)
impeller_unittests!testing::internal::UnitTestImpl::RunAllTests() (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/googletest/googletest/src/gtest.cc:5922)
impeller_unittests!bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/googletest/googletest/src/gtest.cc:2613)
impeller_unittests!bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/googletest/googletest/src/gtest.cc:2668)
impeller_unittests!testing::UnitTest::Run() (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/googletest/googletest/src/gtest.cc:5486)
impeller_unittests!RUN_ALL_TESTS() (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/googletest/googletest/include/gtest/gtest.h:2316)
impeller_unittests!main (/Users/aaclarke/dev/flutter/engine/src/flutter/testing/run_all_unittests.cc:65)
start (Unknown Source:0)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work liste: impellerImpeller rendering backend issues and features requeststeam-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions