| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "flutter/lib/ui/painting/image_generator_registry.h" |
| |
| #include "flutter/fml/mapping.h" |
| #include "flutter/shell/common/shell_test.h" |
| #include "flutter/testing/testing.h" |
| |
| namespace flutter { |
| namespace testing { |
| |
| static sk_sp<SkData> LoadValidImageFixture() { |
| auto fixture_mapping = OpenFixtureAsMapping("DashInNooglerHat.jpg"); |
| |
| // Remap to sk_sp<SkData>. |
| SkData::ReleaseProc on_release = [](const void* ptr, void* context) -> void { |
| delete reinterpret_cast<fml::FileMapping*>(context); |
| }; |
| auto data = SkData::MakeWithProc(fixture_mapping->GetMapping(), |
| fixture_mapping->GetSize(), on_release, |
| fixture_mapping.get()); |
| |
| if (data) { |
| fixture_mapping.release(); |
| } |
| |
| return data; |
| } |
| |
| TEST_F(ShellTest, CreateCompatibleReturnsBuiltinImageGeneratorForValidImage) { |
| auto data = LoadValidImageFixture(); |
| |
| // Fetch the generator and query for basic info |
| ImageGeneratorRegistry registry; |
| auto result = registry.CreateCompatibleGenerator(data); |
| auto info = result->GetInfo(); |
| ASSERT_EQ(info.width(), 3024); |
| ASSERT_EQ(info.height(), 4032); |
| } |
| |
| TEST_F(ShellTest, CreateCompatibleReturnsNullptrForInvalidImage) { |
| ImageGeneratorRegistry registry; |
| auto result = registry.CreateCompatibleGenerator(SkData::MakeEmpty()); |
| ASSERT_EQ(result, nullptr); |
| } |
| |
| class FakeImageGenerator : public ImageGenerator { |
| public: |
| explicit FakeImageGenerator(int identifiableFakeWidth) |
| : info_(SkImageInfo::Make(identifiableFakeWidth, |
| identifiableFakeWidth, |
| SkColorType::kRGBA_8888_SkColorType, |
| SkAlphaType::kOpaque_SkAlphaType)){}; |
| ~FakeImageGenerator() = default; |
| const SkImageInfo& GetInfo() { return info_; } |
| |
| unsigned int GetFrameCount() const { return 1; } |
| |
| unsigned int GetPlayCount() const { return 1; } |
| |
| const ImageGenerator::FrameInfo GetFrameInfo(unsigned int frame_index) const { |
| return {std::nullopt, 0, SkCodecAnimation::DisposalMethod::kKeep}; |
| } |
| |
| SkISize GetScaledDimensions(float scale) { |
| return SkISize::Make(info_.width(), info_.height()); |
| } |
| |
| bool GetPixels(const SkImageInfo& info, |
| void* pixels, |
| size_t row_bytes, |
| unsigned int frame_index, |
| std::optional<unsigned int> prior_frame) { |
| return false; |
| }; |
| |
| private: |
| SkImageInfo info_; |
| }; |
| |
| TEST_F(ShellTest, PositivePriorityTakesPrecedentOverDefaultGenerators) { |
| ImageGeneratorRegistry registry; |
| |
| const int fake_width = 1337; |
| registry.AddFactory( |
| [fake_width](sk_sp<SkData> buffer) { |
| return std::make_unique<FakeImageGenerator>(fake_width); |
| }, |
| 1); |
| |
| // Fetch the generator and query for basic info. |
| auto result = registry.CreateCompatibleGenerator(LoadValidImageFixture()); |
| ASSERT_EQ(result->GetInfo().width(), fake_width); |
| } |
| |
| TEST_F(ShellTest, DefaultGeneratorsTakePrecedentOverNegativePriority) { |
| ImageGeneratorRegistry registry; |
| |
| registry.AddFactory( |
| [](sk_sp<SkData> buffer) { |
| return std::make_unique<FakeImageGenerator>(1337); |
| }, |
| -1); |
| |
| // Fetch the generator and query for basic info. |
| auto result = registry.CreateCompatibleGenerator(LoadValidImageFixture()); |
| // If the real width of the image pops out, then the default generator was |
| // returned rather than the fake one. |
| ASSERT_EQ(result->GetInfo().width(), 3024); |
| } |
| |
| TEST_F(ShellTest, DefaultGeneratorsTakePrecedentOverZeroPriority) { |
| ImageGeneratorRegistry registry; |
| |
| registry.AddFactory( |
| [](sk_sp<SkData> buffer) { |
| return std::make_unique<FakeImageGenerator>(1337); |
| }, |
| 0); |
| |
| // Fetch the generator and query for basic info. |
| auto result = registry.CreateCompatibleGenerator(LoadValidImageFixture()); |
| // If the real width of the image pops out, then the default generator was |
| // returned rather than the fake one. |
| ASSERT_EQ(result->GetInfo().width(), 3024); |
| } |
| |
| TEST_F(ShellTest, ImageGeneratorsWithSamePriorityCascadeChronologically) { |
| ImageGeneratorRegistry registry; |
| |
| // Add 2 factories with the same high priority. |
| registry.AddFactory( |
| [](sk_sp<SkData> buffer) { |
| return std::make_unique<FakeImageGenerator>(1337); |
| }, |
| 5); |
| registry.AddFactory( |
| [](sk_sp<SkData> buffer) { |
| return std::make_unique<FakeImageGenerator>(7777); |
| }, |
| 5); |
| |
| // Feed empty data so that Skia's image generators will reject it, but ours |
| // won't. |
| auto result = registry.CreateCompatibleGenerator(SkData::MakeEmpty()); |
| ASSERT_EQ(result->GetInfo().width(), 1337); |
| } |
| |
| } // namespace testing |
| } // namespace flutter |