From 9554a957ad4c3dc77e1023e9747b84bdaf211a7a Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 1 Nov 2023 09:56:53 -0700 Subject: [PATCH 01/17] [Impeller] added new gaussian blur --- impeller/entity/BUILD.gn | 4 + .../filters/gaussian_blur_filter_contents.cc | 52 +++++++++++ .../filters/gaussian_blur_filter_contents.h | 44 +++++++++ ...gaussian_blur_filter_contents_unittests.cc | 89 +++++++++++++++++++ 4 files changed, 189 insertions(+) create mode 100644 impeller/entity/contents/filters/gaussian_blur_filter_contents.cc create mode 100644 impeller/entity/contents/filters/gaussian_blur_filter_contents.h create mode 100644 impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 3ad9b09136979..1b36f5aab7063 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -162,6 +162,9 @@ impeller_component("entity") { "contents/filters/directional_gaussian_blur_filter_contents.h", "contents/filters/filter_contents.cc", "contents/filters/filter_contents.h", + "contents/filters/gaussian_blur_filter_contents.cc", + "contents/filters/gaussian_blur_filter_contents.h", + "contents/filters/filter_contents.h", "contents/filters/inputs/contents_filter_input.cc", "contents/filters/inputs/contents_filter_input.h", "contents/filters/inputs/filter_contents_filter_input.cc", @@ -269,6 +272,7 @@ impeller_component("entity_unittests") { sources = [ "contents/checkerboard_contents_unittests.cc", + "contents/filters/gaussian_blur_filter_contents_unittests.cc", "contents/filters/inputs/filter_input_unittests.cc", "entity_playground.cc", "entity_playground.h", diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc new file mode 100644 index 0000000000000..a9d2dffa9c0eb --- /dev/null +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -0,0 +1,52 @@ +// 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 "impeller/entity/contents/filters/gaussian_blur_filter_contents.h" + +namespace impeller { + +GaussianBlurFilterContents::GaussianBlurFilterContents(Scalar sigma) + : sigma_(sigma) {} + +std::optional GaussianBlurFilterContents::GetFilterSourceCoverage( + const Matrix& effect_transform, + const Rect& output_limit) const { + return {}; +} + +std::optional GaussianBlurFilterContents::GetFilterCoverage( + const FilterInput::Vector& inputs, + const Entity& entity, + const Matrix& effect_transform) const { + if (inputs.empty()) { + return {}; + } + + std::optional input_coverage = inputs[0]->GetCoverage(entity); + if (!input_coverage.has_value()) { + return {}; + } + + Scalar blur_radius = CalculateBlurRadius(sigma_); + return Rect::MakeLTRB(input_coverage.value().GetLeft() - blur_radius, + input_coverage.value().GetTop() - blur_radius, + input_coverage.value().GetRight() + blur_radius, + input_coverage.value().GetBottom() + blur_radius); +} + +std::optional GaussianBlurFilterContents::RenderFilter( + const FilterInput::Vector& input_textures, + const ContentContext& renderer, + const Entity& entity, + const Matrix& effect_transform, + const Rect& coverage, + const std::optional& coverage_hint) const { + return {}; +} + +Scalar GaussianBlurFilterContents::CalculateBlurRadius(Scalar sigma) { + return static_cast(Sigma(sigma)).radius; +} + +} // namespace impeller diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.h b/impeller/entity/contents/filters/gaussian_blur_filter_contents.h new file mode 100644 index 0000000000000..9e6ab86ffd237 --- /dev/null +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.h @@ -0,0 +1,44 @@ +// 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. + +#pragma once + +#include +#include "impeller/entity/contents/filters/filter_contents.h" + +namespace impeller { + +class GaussianBlurFilterContents final : public FilterContents { + public: + GaussianBlurFilterContents(Scalar sigma = 0.0f); + + Scalar GetSigma() const { return sigma_; } + + // |FilterContents| + std::optional GetFilterSourceCoverage( + const Matrix& effect_transform, + const Rect& output_limit) const override; + + // |FilterContents| + std::optional GetFilterCoverage( + const FilterInput::Vector& inputs, + const Entity& entity, + const Matrix& effect_transform) const override; + + static Scalar CalculateBlurRadius(Scalar sigma); + + private: + // |FilterContents| + std::optional RenderFilter( + const FilterInput::Vector& input_textures, + const ContentContext& renderer, + const Entity& entity, + const Matrix& effect_transform, + const Rect& coverage, + const std::optional& coverage_hint) const override; + + const Scalar sigma_ = 0.0; +}; + +} // namespace impeller diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc new file mode 100644 index 0000000000000..80bdcb215d3ee --- /dev/null +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc @@ -0,0 +1,89 @@ +// 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/testing/testing.h" +#include "gmock/gmock.h" +#include "impeller/entity/contents/filters/gaussian_blur_filter_contents.h" + +namespace impeller { + +using testing::Return; + +namespace { + +class MockTexture : public Texture { + public: + MockTexture(TextureDescriptor desc) : Texture(desc) {} + + MOCK_METHOD(void, SetLabel, (std::string_view label), (override)); + MOCK_METHOD(bool, IsValid, (), (const, override)); + MOCK_METHOD(ISize, GetSize, (), (const, override)); + MOCK_METHOD(bool, + OnSetContents, + (const uint8_t* contents, size_t length, size_t slice), + (override)); + MOCK_METHOD(bool, + OnSetContents, + (std::shared_ptr mapping, size_t slice), + (override)); +}; + +Scalar CalculateSigmaForBlurRadius(Scalar blur_radius) { + // See Sigma.h + return (blur_radius / kKernelRadiusPerSigma) + 0.5; +} +} // namespace + +TEST(GaussianBlurFilterContents, Create) { + GaussianBlurFilterContents contents; + ASSERT_EQ(contents.GetSigma(), 0.0); +} + +TEST(GaussianBlurFilterContents, CoverageEmpty) { + GaussianBlurFilterContents contents; + FilterInput::Vector inputs = {}; + Entity entity; + std::optional coverage = + contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix()); + ASSERT_FALSE(coverage.has_value()); +} + +TEST(GaussianBlurFilterContents, CoverageSimple) { + GaussianBlurFilterContents contents; + FilterInput::Vector inputs = { + FilterInput::Make(Rect::MakeLTRB(10, 10, 110, 110))}; + Entity entity; + std::optional coverage = + contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix()); + ASSERT_EQ(coverage, Rect::MakeLTRB(10, 10, 110, 110)); +} + +TEST(GaussianBlurFilterContents, CoverageWithSigma) { + Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); + GaussianBlurFilterContents contents(/*sigma=*/sigma_radius_1); + FilterInput::Vector inputs = { + FilterInput::Make(Rect::MakeLTRB(100, 100, 200, 200))}; + Entity entity; + std::optional coverage = + contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix()); + ASSERT_EQ(coverage, Rect::MakeLTRB(99, 99, 201, 201)); +} + +TEST(GaussianBlurFilterContents, CoverageWithTexture) { + TextureDescriptor desc = { + .size = ISize(100, 100), + }; + Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); + GaussianBlurFilterContents contents(/*sigma=*/sigma_radius_1); + std::shared_ptr texture = std::make_shared(desc); + EXPECT_CALL(*texture, GetSize()).WillRepeatedly(Return(ISize(100, 100))); + FilterInput::Vector inputs = {FilterInput::Make(texture)}; + Entity entity; + entity.SetTransformation(Matrix::MakeTranslation({100, 100, 0})); + std::optional coverage = + contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix()); + ASSERT_EQ(coverage, Rect::MakeLTRB(99, 99, 201, 201)); +} + +} // namespace impeller From 3d86c8fadce06a7ff12632a4aecf4b6c4dc665ab Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 1 Nov 2023 10:24:13 -0700 Subject: [PATCH 02/17] added directional_gaussian unittests to help --- impeller/entity/BUILD.gn | 4 ++ ...gaussian_blur_filter_contents_unittests.cc | 56 +++++++++++++++++++ .../filters/gaussian_blur_filter_contents.cc | 9 +-- ...gaussian_blur_filter_contents_unittests.cc | 16 ++++++ 4 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 1b36f5aab7063..4c2211dd44d61 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -271,7 +271,11 @@ impeller_component("entity_unittests") { testonly = true sources = [ +<<<<<<< HEAD "contents/checkerboard_contents_unittests.cc", +======= + "contents/filters/directional_gaussian_blur_filter_contents_unittests.cc", +>>>>>>> 8b53b77552 (added directional_gaussian unittests to help) "contents/filters/gaussian_blur_filter_contents_unittests.cc", "contents/filters/inputs/filter_input_unittests.cc", "entity_playground.cc", diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc new file mode 100644 index 0000000000000..88ef964aee152 --- /dev/null +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -0,0 +1,56 @@ +// 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/testing/testing.h" +#include "gmock/gmock.h" +#include "impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.h" + +namespace impeller { + +using testing::Return; + +namespace { + +class MockTexture : public Texture { + public: + MockTexture(TextureDescriptor desc) : Texture(desc) {} + + MOCK_METHOD(void, SetLabel, (std::string_view label), (override)); + MOCK_METHOD(bool, IsValid, (), (const, override)); + MOCK_METHOD(ISize, GetSize, (), (const, override)); + MOCK_METHOD(bool, + OnSetContents, + (const uint8_t* contents, size_t length, size_t slice), + (override)); + MOCK_METHOD(bool, + OnSetContents, + (std::shared_ptr mapping, size_t slice), + (override)); +}; + +Scalar CalculateSigmaForBlurRadius(Scalar blur_radius) { + // See Sigma.h + return (blur_radius / kKernelRadiusPerSigma) + 0.5; +} +} // namespace + +TEST(DirectionalGaussianBlurFilterContents, CoverageWithEffectTransform) { + TextureDescriptor desc = { + .size = ISize(100, 100), + }; + Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); + auto contents = std::make_unique(); + contents->SetSigma(Sigma{sigma_radius_1}); + contents->SetDirection({1.0, 0.0}); + std::shared_ptr texture = std::make_shared(desc); + EXPECT_CALL(*texture, GetSize()).WillRepeatedly(Return(ISize(100, 100))); + FilterInput::Vector inputs = {FilterInput::Make(texture)}; + Entity entity; + entity.SetTransformation(Matrix::MakeTranslation({100, 100, 0})); + std::optional coverage = contents->GetFilterCoverage( + inputs, entity, /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0})); + ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100, 200 + 2, 200)); +} + +} // namespace impeller diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index a9d2dffa9c0eb..8bb339ed7eeaf 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -29,10 +29,11 @@ std::optional GaussianBlurFilterContents::GetFilterCoverage( } Scalar blur_radius = CalculateBlurRadius(sigma_); - return Rect::MakeLTRB(input_coverage.value().GetLeft() - blur_radius, - input_coverage.value().GetTop() - blur_radius, - input_coverage.value().GetRight() + blur_radius, - input_coverage.value().GetBottom() + blur_radius); + Vector3 blur_radii = effect_transform.Basis() * Vector3{blur_radius, blur_radius, 0.0}; + return Rect::MakeLTRB(input_coverage.value().GetLeft() - blur_radii.y, + input_coverage.value().GetTop() - blur_radii.x, + input_coverage.value().GetRight() + blur_radii.x, + input_coverage.value().GetBottom() + blur_radii.y); } std::optional GaussianBlurFilterContents::RenderFilter( diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc index 80bdcb215d3ee..f1e5fb2472849 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc @@ -86,4 +86,20 @@ TEST(GaussianBlurFilterContents, CoverageWithTexture) { ASSERT_EQ(coverage, Rect::MakeLTRB(99, 99, 201, 201)); } +TEST(GaussianBlurFilterContents, CoverageWithEffectTransform) { + TextureDescriptor desc = { + .size = ISize(100, 100), + }; + Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); + GaussianBlurFilterContents contents(/*sigma=*/sigma_radius_1); + std::shared_ptr texture = std::make_shared(desc); + EXPECT_CALL(*texture, GetSize()).WillRepeatedly(Return(ISize(100, 100))); + FilterInput::Vector inputs = {FilterInput::Make(texture)}; + Entity entity; + entity.SetTransformation(Matrix::MakeTranslation({100, 100, 0})); + std::optional coverage = contents.GetFilterCoverage( + inputs, entity, /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0})); + ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2)); +} + } // namespace impeller From 48c754ef358fc17b034d315038a68fb11ae43ce5 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 1 Nov 2023 10:47:42 -0700 Subject: [PATCH 03/17] added filtersourcecoverage --- impeller/entity/BUILD.gn | 2 +- ...ional_gaussian_blur_filter_contents_unittests.cc | 11 +++++++++++ .../filters/gaussian_blur_filter_contents.cc | 13 +++++++------ .../filters/gaussian_blur_filter_contents.h | 8 ++++++-- .../gaussian_blur_filter_contents_unittests.cc | 9 +++++++++ 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 4c2211dd44d61..306c4035bbce1 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -162,9 +162,9 @@ impeller_component("entity") { "contents/filters/directional_gaussian_blur_filter_contents.h", "contents/filters/filter_contents.cc", "contents/filters/filter_contents.h", + "contents/filters/filter_contents.h", "contents/filters/gaussian_blur_filter_contents.cc", "contents/filters/gaussian_blur_filter_contents.h", - "contents/filters/filter_contents.h", "contents/filters/inputs/contents_filter_input.cc", "contents/filters/inputs/contents_filter_input.h", "contents/filters/inputs/filter_contents_filter_input.cc", diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc index 88ef964aee152..1b25759e961f7 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -53,4 +53,15 @@ TEST(DirectionalGaussianBlurFilterContents, CoverageWithEffectTransform) { ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100, 200 + 2, 200)); } +TEST(DirectionalGaussianBlurFilterContents, FilterSourceCoverage) { + Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); + auto contents = std::make_unique(); + contents->SetSigma(Sigma{sigma_radius_1}); + contents->SetDirection({1.0, 0.0}); + std::optional coverage = contents->GetFilterSourceCoverage( + /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}), + /*output_limit=*/Rect::MakeLTRB(100, 100, 200, 200)); + ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100, 200 + 2, 200)); +} + } // namespace impeller diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index 8bb339ed7eeaf..054b67bf08513 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -12,7 +12,10 @@ GaussianBlurFilterContents::GaussianBlurFilterContents(Scalar sigma) std::optional GaussianBlurFilterContents::GetFilterSourceCoverage( const Matrix& effect_transform, const Rect& output_limit) const { - return {}; + Scalar blur_radius = CalculateBlurRadius(sigma_); + Vector3 blur_radii = + effect_transform.Basis() * Vector3{blur_radius, blur_radius, 0.0}; + return output_limit.Expand(Point(blur_radii.x, blur_radii.y)); } std::optional GaussianBlurFilterContents::GetFilterCoverage( @@ -29,11 +32,9 @@ std::optional GaussianBlurFilterContents::GetFilterCoverage( } Scalar blur_radius = CalculateBlurRadius(sigma_); - Vector3 blur_radii = effect_transform.Basis() * Vector3{blur_radius, blur_radius, 0.0}; - return Rect::MakeLTRB(input_coverage.value().GetLeft() - blur_radii.y, - input_coverage.value().GetTop() - blur_radii.x, - input_coverage.value().GetRight() + blur_radii.x, - input_coverage.value().GetBottom() + blur_radii.y); + Vector3 blur_radii = + effect_transform.Basis() * Vector3{blur_radius, blur_radius, 0.0}; + return input_coverage.value().Expand(Point(blur_radii.x, blur_radii.y)); } std::optional GaussianBlurFilterContents::RenderFilter( diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.h b/impeller/entity/contents/filters/gaussian_blur_filter_contents.h index 9e6ab86ffd237..68ee98e8d18f1 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.h +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.h @@ -9,10 +9,14 @@ namespace impeller { +/// Performs a bidirectional Gaussian blur. +/// +/// This is accomplished by rendering multiple passes in multiple directions. +/// Note: This will replace `DirectionalGaussianBlurFilterContents`. class GaussianBlurFilterContents final : public FilterContents { public: GaussianBlurFilterContents(Scalar sigma = 0.0f); - + Scalar GetSigma() const { return sigma_; } // |FilterContents| @@ -41,4 +45,4 @@ class GaussianBlurFilterContents final : public FilterContents { const Scalar sigma_ = 0.0; }; -} // namespace impeller +} // namespace impeller diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc index f1e5fb2472849..5024731d67851 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc @@ -102,4 +102,13 @@ TEST(GaussianBlurFilterContents, CoverageWithEffectTransform) { ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2)); } +TEST(GaussianBlurFilterContents, FilterSourceCoverage) { + Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); + auto contents = std::make_unique(sigma_radius_1); + std::optional coverage = contents->GetFilterSourceCoverage( + /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}), + /*output_limit=*/Rect::MakeLTRB(100, 100, 200, 200)); + ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2)); +} + } // namespace impeller From d61ac9662a054e172797bbc764afd734c4593141 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 1 Nov 2023 15:48:51 -0700 Subject: [PATCH 04/17] added more tests --- ...gaussian_blur_filter_contents_unittests.cc | 42 +++++++++++-------- ...gaussian_blur_filter_contents_unittests.cc | 22 ++-------- impeller/renderer/testing/mocks.h | 26 ++++++++++++ 3 files changed, 54 insertions(+), 36 deletions(-) diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc index 1b25759e961f7..050eeb3c8b879 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -4,31 +4,17 @@ #include "flutter/testing/testing.h" #include "gmock/gmock.h" +#include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.h" +#include "impeller/renderer/testing/mocks.h" namespace impeller { +namespace testing { -using testing::Return; +using ::testing::Return; namespace { -class MockTexture : public Texture { - public: - MockTexture(TextureDescriptor desc) : Texture(desc) {} - - MOCK_METHOD(void, SetLabel, (std::string_view label), (override)); - MOCK_METHOD(bool, IsValid, (), (const, override)); - MOCK_METHOD(ISize, GetSize, (), (const, override)); - MOCK_METHOD(bool, - OnSetContents, - (const uint8_t* contents, size_t length, size_t slice), - (override)); - MOCK_METHOD(bool, - OnSetContents, - (std::shared_ptr mapping, size_t slice), - (override)); -}; - Scalar CalculateSigmaForBlurRadius(Scalar blur_radius) { // See Sigma.h return (blur_radius / kKernelRadiusPerSigma) + 0.5; @@ -64,4 +50,24 @@ TEST(DirectionalGaussianBlurFilterContents, FilterSourceCoverage) { ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100, 200 + 2, 200)); } +TEST(DirectionalGaussianBlurFilterContents, RenderNothing) { + Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); + auto contents = std::make_unique(); + contents->SetSigma(Sigma{sigma_radius_1}); + contents->SetDirection({1.0, 0.0}); + auto mock_context = std::make_shared(); + auto mock_typographer_context = std::make_shared(); + auto mock_allocator = std::make_shared(); + auto mock_render_target_allocator = + std::make_shared(mock_allocator); + ContentContext renderer(mock_context, mock_typographer_context, + mock_render_target_allocator); + Entity entity; + Rect coverage_hint = Rect::MakeLTRB(0, 0, 0, 0); + std::optional result = + contents->GetEntity(renderer, entity, coverage_hint); + ASSERT_FALSE(result.has_value()); +} + +} // namespace testing } // namespace impeller diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc index 5024731d67851..9e308ee4820ac 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc @@ -5,30 +5,15 @@ #include "flutter/testing/testing.h" #include "gmock/gmock.h" #include "impeller/entity/contents/filters/gaussian_blur_filter_contents.h" +#include "impeller/renderer/testing/mocks.h" namespace impeller { +namespace testing { -using testing::Return; +using ::testing::Return; namespace { -class MockTexture : public Texture { - public: - MockTexture(TextureDescriptor desc) : Texture(desc) {} - - MOCK_METHOD(void, SetLabel, (std::string_view label), (override)); - MOCK_METHOD(bool, IsValid, (), (const, override)); - MOCK_METHOD(ISize, GetSize, (), (const, override)); - MOCK_METHOD(bool, - OnSetContents, - (const uint8_t* contents, size_t length, size_t slice), - (override)); - MOCK_METHOD(bool, - OnSetContents, - (std::shared_ptr mapping, size_t slice), - (override)); -}; - Scalar CalculateSigmaForBlurRadius(Scalar blur_radius) { // See Sigma.h return (blur_radius / kKernelRadiusPerSigma) + 0.5; @@ -111,4 +96,5 @@ TEST(GaussianBlurFilterContents, FilterSourceCoverage) { ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2)); } +} // namespace testing } // namespace impeller diff --git a/impeller/renderer/testing/mocks.h b/impeller/renderer/testing/mocks.h index 8d50ac115c27b..92dd17bef4998 100644 --- a/impeller/renderer/testing/mocks.h +++ b/impeller/renderer/testing/mocks.h @@ -10,6 +10,7 @@ #include "impeller/renderer/command_buffer.h" #include "impeller/renderer/context.h" #include "impeller/renderer/render_target.h" +#include "impeller/typographer/typographer_context.h" namespace impeller { namespace testing { @@ -164,5 +165,30 @@ class MockTexture : public Texture { (override)); }; +class MockTypographerContext : public TypographerContext { + public: + MOCK_METHOD(std::shared_ptr, + CreateGlyphAtlas, + (Context & context, + GlyphAtlas::Type type, + std::shared_ptr atlas_context, + const FontGlyphMap& font_glyph_map), + (const, override)); + MOCK_METHOD(std::shared_ptr, + CreateGlyphAtlasContext, + (), + (const, override)); +}; + +class MockRenderTargetAllocator : public RenderTargetAllocator { + public: + MockRenderTargetAllocator(std::shared_ptr allocator) + : RenderTargetAllocator(allocator) {} + MOCK_METHOD(std::shared_ptr, + CreateTexture, + (const TextureDescriptor& desc), + (override)); +}; + } // namespace testing } // namespace impeller From 789a5da1a70ea5ee772d554ddcd4d7cd2e1bd018 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 2 Nov 2023 14:38:06 -0700 Subject: [PATCH 05/17] got a possitive rendering test --- ...gaussian_blur_filter_contents_unittests.cc | 99 ++++++++++++++++++- impeller/renderer/testing/mocks.h | 86 ++++++++++++++++ 2 files changed, 182 insertions(+), 3 deletions(-) diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc index 050eeb3c8b879..a2c8df040c8d5 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -11,7 +11,11 @@ namespace impeller { namespace testing { +using ::testing::_; +using ::testing::An; +using ::testing::Invoke; using ::testing::Return; +using ::testing::ReturnRef; namespace { @@ -21,7 +25,16 @@ Scalar CalculateSigmaForBlurRadius(Scalar blur_radius) { } } // namespace -TEST(DirectionalGaussianBlurFilterContents, CoverageWithEffectTransform) { +class DirectionalGaussianBlurFilterContentsTest : public ::testing::Test { + public: + void SetUp() override { capabilities_ = mock_capabilities_; } + + std::shared_ptr mock_capabilities_ = + std::make_shared(); + std::shared_ptr capabilities_; +}; + +TEST_F(DirectionalGaussianBlurFilterContentsTest, CoverageWithEffectTransform) { TextureDescriptor desc = { .size = ISize(100, 100), }; @@ -39,7 +52,7 @@ TEST(DirectionalGaussianBlurFilterContents, CoverageWithEffectTransform) { ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100, 200 + 2, 200)); } -TEST(DirectionalGaussianBlurFilterContents, FilterSourceCoverage) { +TEST_F(DirectionalGaussianBlurFilterContentsTest, FilterSourceCoverage) { Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); auto contents = std::make_unique(); contents->SetSigma(Sigma{sigma_radius_1}); @@ -50,7 +63,7 @@ TEST(DirectionalGaussianBlurFilterContents, FilterSourceCoverage) { ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100, 200 + 2, 200)); } -TEST(DirectionalGaussianBlurFilterContents, RenderNothing) { +TEST_F(DirectionalGaussianBlurFilterContentsTest, RenderNoCoverage) { Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); auto contents = std::make_unique(); contents->SetSigma(Sigma{sigma_radius_1}); @@ -69,5 +82,85 @@ TEST(DirectionalGaussianBlurFilterContents, RenderNothing) { ASSERT_FALSE(result.has_value()); } +TEST_F(DirectionalGaussianBlurFilterContentsTest, RenderSomething) { + TextureDescriptor desc = { + .size = ISize(100, 100), + }; + std::shared_ptr texture = std::make_shared(desc); + EXPECT_CALL(*texture, GetSize()).WillRepeatedly(Return(ISize(100, 100))); + Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); + auto contents = std::make_unique(); + contents->SetSigma(Sigma{sigma_radius_1}); + contents->SetDirection({1.0, 0.0}); + contents->SetInputs({FilterInput::Make(texture)}); + auto mock_context = std::make_shared(); + EXPECT_CALL(*mock_context, GetCapabilities()) + .WillRepeatedly(ReturnRef(capabilities_)); + EXPECT_CALL(*mock_context, IsValid()).WillRepeatedly(Return(true)); + auto mock_sampler_library = std::make_shared(); + auto mock_shader_library = std::make_shared(); + auto mock_pipeline_library = std::make_shared(); + EXPECT_CALL(*mock_pipeline_library, GetPipeline(An())) + .WillRepeatedly( + Invoke([&mock_pipeline_library](PipelineDescriptor descriptor) { + PipelineFuture result; + std::promise>> promise; + auto mock_pipeline = + std::make_shared>( + mock_pipeline_library, descriptor); + EXPECT_CALL(*mock_pipeline, IsValid()).WillRepeatedly(Return(true)); + promise.set_value(mock_pipeline); + result.descriptor = descriptor; + result.future = promise.get_future(); + return result; + })); + EXPECT_CALL(*mock_shader_library, GetFunction(_, _)) + .WillRepeatedly(Invoke([](std::string_view name, ShaderStage stage) { + return std::make_shared(UniqueID(), + std::string(name), stage); + })); + EXPECT_CALL(*mock_context, GetSamplerLibrary()) + .WillRepeatedly(Return(mock_sampler_library)); + EXPECT_CALL(*mock_context, GetShaderLibrary()) + .WillRepeatedly(Return(mock_shader_library)); + EXPECT_CALL(*mock_context, GetPipelineLibrary()) + .WillRepeatedly(Return(mock_pipeline_library)); + EXPECT_CALL(*mock_context, CreateCommandBuffer()) + .WillRepeatedly(Invoke(([&mock_context]() { + auto result = std::make_shared(mock_context); + EXPECT_CALL(*result, IsValid()).WillRepeatedly(Return(true)); + EXPECT_CALL(*result, OnSubmitCommands(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(*result, OnCreateRenderPass(_)) + .WillRepeatedly( + Invoke(([&mock_context](const RenderTarget& render_target) { + auto result = std::make_shared(mock_context, + render_target); + EXPECT_CALL(*result, IsValid).WillRepeatedly(Return(true)); + EXPECT_CALL(*result, OnEncodeCommands(_)) + .WillRepeatedly(Return(true)); + return result; + }))); + return result; + }))); + auto mock_typographer_context = std::make_shared(); + auto mock_allocator = std::make_shared(); + auto mock_render_target_allocator = + std::make_shared(mock_allocator); + EXPECT_CALL(*mock_render_target_allocator, CreateTexture(_)) + .WillRepeatedly(Invoke(([](const TextureDescriptor& desc) { + auto result = std::make_shared(desc); + EXPECT_CALL(*result, IsValid()).WillRepeatedly(Return(true)); + return result; + }))); + ContentContext renderer(mock_context, mock_typographer_context, + mock_render_target_allocator); + Entity entity; + Rect coverage_hint = Rect::MakeLTRB(0, 0, 0, 0); + std::optional result = + contents->GetEntity(renderer, entity, coverage_hint); + ASSERT_TRUE(result.has_value()); + ASSERT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver); +} + } // namespace testing } // namespace impeller diff --git a/impeller/renderer/testing/mocks.h b/impeller/renderer/testing/mocks.h index 92dd17bef4998..5d6ae779926a7 100644 --- a/impeller/renderer/testing/mocks.h +++ b/impeller/renderer/testing/mocks.h @@ -9,7 +9,11 @@ #include "impeller/core/texture.h" #include "impeller/renderer/command_buffer.h" #include "impeller/renderer/context.h" +#include "impeller/renderer/pipeline_library.h" +#include "impeller/renderer/render_pass.h" #include "impeller/renderer/render_target.h" +#include "impeller/renderer/sampler_library.h" +#include "impeller/renderer/shader_function.h" #include "impeller/typographer/typographer_context.h" namespace impeller { @@ -190,5 +194,87 @@ class MockRenderTargetAllocator : public RenderTargetAllocator { (override)); }; +class MockCapabilities : public Capabilities { + public: + MOCK_METHOD(bool, SupportsOffscreenMSAA, (), (const, override)); + MOCK_METHOD(bool, SupportsSSBO, (), (const, override)); + MOCK_METHOD(bool, SupportsBufferToTextureBlits, (), (const, override)); + MOCK_METHOD(bool, SupportsTextureToTextureBlits, (), (const, override)); + MOCK_METHOD(bool, SupportsFramebufferFetch, (), (const, override)); + MOCK_METHOD(bool, SupportsCompute, (), (const, override)); + MOCK_METHOD(bool, SupportsComputeSubgroups, (), (const, override)); + MOCK_METHOD(bool, SupportsReadFromOnscreenTexture, (), (const, override)); + MOCK_METHOD(bool, SupportsReadFromResolve, (), (const, override)); + MOCK_METHOD(bool, SupportsDecalSamplerAddressMode, (), (const, override)); + MOCK_METHOD(bool, SupportsDeviceTransientTextures, (), (const, override)); + MOCK_METHOD(PixelFormat, GetDefaultColorFormat, (), (const, override)); + MOCK_METHOD(PixelFormat, GetDefaultStencilFormat, (), (const, override)); + MOCK_METHOD(PixelFormat, GetDefaultDepthStencilFormat, (), (const, override)); +}; + +class MockRenderPass : public RenderPass { + public: + MockRenderPass(std::weak_ptr context, + const RenderTarget& target) + : RenderPass(context, target) {} + MOCK_METHOD(bool, IsValid, (), (const, override)); + MOCK_METHOD(void, OnSetLabel, (std::string), (override)); + MOCK_METHOD(bool, OnEncodeCommands, (const Context&), (const, override)); +}; + +class MockSamplerLibrary : public SamplerLibrary { + public: + MOCK_METHOD(std::shared_ptr, + GetSampler, + (SamplerDescriptor), + (override)); +}; + +class MockShaderLibrary : public ShaderLibrary { + public: + MOCK_METHOD(bool, IsValid, (), (const, override)); + MOCK_METHOD(std::shared_ptr, + GetFunction, + (std::string_view name, ShaderStage stage), + (override)); + MOCK_METHOD(void, + UnregisterFunction, + (std::string name, ShaderStage stage), + (override)); +}; + +class MockShaderFunction : public ShaderFunction { + public: + MockShaderFunction(UniqueID parent_library_id, + std::string name, + ShaderStage stage) + : ShaderFunction(parent_library_id, name, stage) {} +}; + +class MockPipelineLibrary : public PipelineLibrary { + public: + MOCK_METHOD(bool, IsValid, (), (const, override)); + MOCK_METHOD(PipelineFuture, + GetPipeline, + (PipelineDescriptor descriptor), + (override)); + MOCK_METHOD(PipelineFuture, + GetPipeline, + (ComputePipelineDescriptor descriptor), + (override)); + MOCK_METHOD(void, + RemovePipelinesWithEntryPoint, + (std::shared_ptr function), + (override)); +}; + +template +class MockPipeline : public Pipeline { + public: + MockPipeline(std::weak_ptr library, T desc) + : Pipeline(library, desc) {} + MOCK_METHOD(bool, IsValid, (), (const, override)); +}; + } // namespace testing } // namespace impeller From 348f8ee074f5cd336ff0d0ff13ebf91f81eb1feb Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 2 Nov 2023 15:24:25 -0700 Subject: [PATCH 06/17] refactor --- ...gaussian_blur_filter_contents_unittests.cc | 143 ++++++++++-------- 1 file changed, 81 insertions(+), 62 deletions(-) diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc index a2c8df040c8d5..37136f874a21d 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -27,10 +27,87 @@ Scalar CalculateSigmaForBlurRadius(Scalar blur_radius) { class DirectionalGaussianBlurFilterContentsTest : public ::testing::Test { public: - void SetUp() override { capabilities_ = mock_capabilities_; } + void SetUp() override { + mock_render_target_allocator_ = + std::make_shared(mock_allocator_); + capabilities_ = mock_capabilities_; + } + // Stubs in the minimal support to make rendering pass. + void SetupMinimalContext() { + EXPECT_CALL(*mock_context_, GetCapabilities()) + .WillRepeatedly(ReturnRef(capabilities_)); + EXPECT_CALL(*mock_context_, IsValid()).WillRepeatedly(Return(true)); + EXPECT_CALL(*mock_pipeline_library_, GetPipeline(An())) + .WillRepeatedly(Invoke([mock_pipeline_library = + std::weak_ptr( + mock_pipeline_library_)]( + PipelineDescriptor descriptor) { + PipelineFuture result; + std::promise>> promise; + auto mock_pipeline = + std::make_shared>( + mock_pipeline_library, descriptor); + EXPECT_CALL(*mock_pipeline, IsValid()).WillRepeatedly(Return(true)); + promise.set_value(mock_pipeline); + result.descriptor = descriptor; + result.future = promise.get_future(); + return result; + })); + EXPECT_CALL(*mock_shader_library_, GetFunction(_, _)) + .WillRepeatedly(Invoke([](std::string_view name, ShaderStage stage) { + return std::make_shared(UniqueID(), + std::string(name), stage); + })); + EXPECT_CALL(*mock_context_, GetSamplerLibrary()) + .WillRepeatedly(Return(mock_sampler_library_)); + EXPECT_CALL(*mock_context_, GetShaderLibrary()) + .WillRepeatedly(Return(mock_shader_library_)); + EXPECT_CALL(*mock_context_, GetPipelineLibrary()) + .WillRepeatedly(Return(mock_pipeline_library_)); + EXPECT_CALL(*mock_context_, CreateCommandBuffer()) + .WillRepeatedly(Invoke(([mock_context = + std::weak_ptr( + mock_context_)]() { + auto result = std::make_shared(mock_context); + EXPECT_CALL(*result, IsValid()).WillRepeatedly(Return(true)); + EXPECT_CALL(*result, OnSubmitCommands(_)) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*result, OnCreateRenderPass(_)) + .WillRepeatedly( + Invoke(([mock_context](const RenderTarget& render_target) { + auto result = std::make_shared( + mock_context, render_target); + EXPECT_CALL(*result, IsValid).WillRepeatedly(Return(true)); + EXPECT_CALL(*result, OnEncodeCommands(_)) + .WillRepeatedly(Return(true)); + return result; + }))); + return result; + }))); + EXPECT_CALL(*mock_render_target_allocator_, CreateTexture(_)) + .WillRepeatedly(Invoke(([](const TextureDescriptor& desc) { + auto result = std::make_shared(desc); + EXPECT_CALL(*result, IsValid()).WillRepeatedly(Return(true)); + return result; + }))); + } + + std::shared_ptr mock_context_ = + std::make_shared(); std::shared_ptr mock_capabilities_ = std::make_shared(); + std::shared_ptr mock_sampler_library_ = + std::make_shared(); + std::shared_ptr mock_shader_library_ = + std::make_shared(); + std::shared_ptr mock_pipeline_library_ = + std::make_shared(); + std::shared_ptr mock_typographer_context_ = + std::make_shared(); + std::shared_ptr mock_allocator_ = + std::make_shared(); + std::shared_ptr mock_render_target_allocator_; std::shared_ptr capabilities_; }; @@ -83,6 +160,7 @@ TEST_F(DirectionalGaussianBlurFilterContentsTest, RenderNoCoverage) { } TEST_F(DirectionalGaussianBlurFilterContentsTest, RenderSomething) { + SetupMinimalContext(); TextureDescriptor desc = { .size = ISize(100, 100), }; @@ -93,67 +171,8 @@ TEST_F(DirectionalGaussianBlurFilterContentsTest, RenderSomething) { contents->SetSigma(Sigma{sigma_radius_1}); contents->SetDirection({1.0, 0.0}); contents->SetInputs({FilterInput::Make(texture)}); - auto mock_context = std::make_shared(); - EXPECT_CALL(*mock_context, GetCapabilities()) - .WillRepeatedly(ReturnRef(capabilities_)); - EXPECT_CALL(*mock_context, IsValid()).WillRepeatedly(Return(true)); - auto mock_sampler_library = std::make_shared(); - auto mock_shader_library = std::make_shared(); - auto mock_pipeline_library = std::make_shared(); - EXPECT_CALL(*mock_pipeline_library, GetPipeline(An())) - .WillRepeatedly( - Invoke([&mock_pipeline_library](PipelineDescriptor descriptor) { - PipelineFuture result; - std::promise>> promise; - auto mock_pipeline = - std::make_shared>( - mock_pipeline_library, descriptor); - EXPECT_CALL(*mock_pipeline, IsValid()).WillRepeatedly(Return(true)); - promise.set_value(mock_pipeline); - result.descriptor = descriptor; - result.future = promise.get_future(); - return result; - })); - EXPECT_CALL(*mock_shader_library, GetFunction(_, _)) - .WillRepeatedly(Invoke([](std::string_view name, ShaderStage stage) { - return std::make_shared(UniqueID(), - std::string(name), stage); - })); - EXPECT_CALL(*mock_context, GetSamplerLibrary()) - .WillRepeatedly(Return(mock_sampler_library)); - EXPECT_CALL(*mock_context, GetShaderLibrary()) - .WillRepeatedly(Return(mock_shader_library)); - EXPECT_CALL(*mock_context, GetPipelineLibrary()) - .WillRepeatedly(Return(mock_pipeline_library)); - EXPECT_CALL(*mock_context, CreateCommandBuffer()) - .WillRepeatedly(Invoke(([&mock_context]() { - auto result = std::make_shared(mock_context); - EXPECT_CALL(*result, IsValid()).WillRepeatedly(Return(true)); - EXPECT_CALL(*result, OnSubmitCommands(_)).WillRepeatedly(Return(true)); - EXPECT_CALL(*result, OnCreateRenderPass(_)) - .WillRepeatedly( - Invoke(([&mock_context](const RenderTarget& render_target) { - auto result = std::make_shared(mock_context, - render_target); - EXPECT_CALL(*result, IsValid).WillRepeatedly(Return(true)); - EXPECT_CALL(*result, OnEncodeCommands(_)) - .WillRepeatedly(Return(true)); - return result; - }))); - return result; - }))); - auto mock_typographer_context = std::make_shared(); - auto mock_allocator = std::make_shared(); - auto mock_render_target_allocator = - std::make_shared(mock_allocator); - EXPECT_CALL(*mock_render_target_allocator, CreateTexture(_)) - .WillRepeatedly(Invoke(([](const TextureDescriptor& desc) { - auto result = std::make_shared(desc); - EXPECT_CALL(*result, IsValid()).WillRepeatedly(Return(true)); - return result; - }))); - ContentContext renderer(mock_context, mock_typographer_context, - mock_render_target_allocator); + ContentContext renderer(mock_context_, mock_typographer_context_, + mock_render_target_allocator_); Entity entity; Rect coverage_hint = Rect::MakeLTRB(0, 0, 0, 0); std::optional result = From b7a328ef57b7bf1490bd8396c8cea334494d4c23 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 3 Nov 2023 10:15:14 -0700 Subject: [PATCH 07/17] added coverage fix --- impeller/entity/BUILD.gn | 3 --- ...irectional_gaussian_blur_filter_contents.cc | 4 +++- ..._gaussian_blur_filter_contents_unittests.cc | 18 +++++++++++++++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 306c4035bbce1..b4524f4567deb 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -271,11 +271,8 @@ impeller_component("entity_unittests") { testonly = true sources = [ -<<<<<<< HEAD "contents/checkerboard_contents_unittests.cc", -======= "contents/filters/directional_gaussian_blur_filter_contents_unittests.cc", ->>>>>>> 8b53b77552 (added directional_gaussian unittests to help) "contents/filters/gaussian_blur_filter_contents_unittests.cc", "contents/filters/inputs/filter_input_unittests.cc", "entity_playground.cc", diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.cc index 94145261e57ba..e7bdf15efa41a 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.cc @@ -313,7 +313,9 @@ std::optional DirectionalGaussianBlurFilterContents::GetFilterCoverage( auto transform = inputs[0]->GetTransform(entity) * effect_transform.Basis(); auto transformed_blur_vector = - transform.TransformDirection(blur_direction_ * Radius{blur_sigma_}.radius) + transform + .TransformDirection(blur_direction_ * + Radius{ScaleSigma(blur_sigma_)}.radius) .Abs(); return coverage->Expand(transformed_blur_vector); } diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc index 37136f874a21d..c567eb810564c 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -89,6 +89,7 @@ class DirectionalGaussianBlurFilterContentsTest : public ::testing::Test { .WillRepeatedly(Invoke(([](const TextureDescriptor& desc) { auto result = std::make_shared(desc); EXPECT_CALL(*result, IsValid()).WillRepeatedly(Return(true)); + EXPECT_CALL(*result, GetSize()).WillRepeatedly(Return(desc.size)); return result; }))); } @@ -174,11 +175,22 @@ TEST_F(DirectionalGaussianBlurFilterContentsTest, RenderSomething) { ContentContext renderer(mock_context_, mock_typographer_context_, mock_render_target_allocator_); Entity entity; - Rect coverage_hint = Rect::MakeLTRB(0, 0, 0, 0); std::optional result = - contents->GetEntity(renderer, entity, coverage_hint); + contents->GetEntity(renderer, entity, /*coverage_hint=*/{}); ASSERT_TRUE(result.has_value()); - ASSERT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver); + EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver); + std::optional result_coverage = result.value().GetCoverage(); + std::optional contents_coverage = contents->GetCoverage(entity); + EXPECT_TRUE(result_coverage.has_value()); + EXPECT_TRUE(contents_coverage.has_value()); + EXPECT_NEAR(result_coverage.value().GetLeft(), + contents_coverage.value().GetLeft(), kEhCloseEnough); + EXPECT_NEAR(result_coverage.value().GetTop(), + contents_coverage.value().GetTop(), kEhCloseEnough); + EXPECT_NEAR(result_coverage.value().GetRight(), + contents_coverage.value().GetRight(), kEhCloseEnough); + EXPECT_NEAR(result_coverage.value().GetBottom(), + contents_coverage.value().GetBottom(), kEhCloseEnough); } } // namespace testing From 88e7f352e05ffe602f98d0873dd6023f4a5dd9d2 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 3 Nov 2023 11:33:01 -0700 Subject: [PATCH 08/17] removed stray gaussian blur files --- ci/licenses_golden/licenses_flutter | 4 + impeller/entity/BUILD.gn | 4 - .../filters/gaussian_blur_filter_contents.cc | 54 ---------- .../filters/gaussian_blur_filter_contents.h | 48 --------- ...gaussian_blur_filter_contents_unittests.cc | 100 ------------------ impeller/renderer/testing/mocks.h | 1 + 6 files changed, 5 insertions(+), 206 deletions(-) delete mode 100644 impeller/entity/contents/filters/gaussian_blur_filter_contents.cc delete mode 100644 impeller/entity/contents/filters/gaussian_blur_filter_contents.h delete mode 100644 impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 7ed7a51cbc2db..ef656b3972b56 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -3058,6 +3058,8 @@ ORIGIN: ../../../flutter/impeller/entity/contents/filters/directional_gaussian_b ORIGIN: ../../../flutter/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/contents/filters/filter_contents.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/contents/filters/filter_contents.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/contents_filter_input.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/contents_filter_input.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc + ../../../flutter/LICENSE @@ -5841,6 +5843,8 @@ FILE: ../../../flutter/impeller/entity/contents/filters/directional_gaussian_blu FILE: ../../../flutter/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.h FILE: ../../../flutter/impeller/entity/contents/filters/filter_contents.cc FILE: ../../../flutter/impeller/entity/contents/filters/filter_contents.h +FILE: ../../../flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +FILE: ../../../flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents.h FILE: ../../../flutter/impeller/entity/contents/filters/inputs/contents_filter_input.cc FILE: ../../../flutter/impeller/entity/contents/filters/inputs/contents_filter_input.h FILE: ../../../flutter/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index b4524f4567deb..726c53fab1c08 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -162,9 +162,6 @@ impeller_component("entity") { "contents/filters/directional_gaussian_blur_filter_contents.h", "contents/filters/filter_contents.cc", "contents/filters/filter_contents.h", - "contents/filters/filter_contents.h", - "contents/filters/gaussian_blur_filter_contents.cc", - "contents/filters/gaussian_blur_filter_contents.h", "contents/filters/inputs/contents_filter_input.cc", "contents/filters/inputs/contents_filter_input.h", "contents/filters/inputs/filter_contents_filter_input.cc", @@ -273,7 +270,6 @@ impeller_component("entity_unittests") { sources = [ "contents/checkerboard_contents_unittests.cc", "contents/filters/directional_gaussian_blur_filter_contents_unittests.cc", - "contents/filters/gaussian_blur_filter_contents_unittests.cc", "contents/filters/inputs/filter_input_unittests.cc", "entity_playground.cc", "entity_playground.h", diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc deleted file mode 100644 index 054b67bf08513..0000000000000 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ /dev/null @@ -1,54 +0,0 @@ -// 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 "impeller/entity/contents/filters/gaussian_blur_filter_contents.h" - -namespace impeller { - -GaussianBlurFilterContents::GaussianBlurFilterContents(Scalar sigma) - : sigma_(sigma) {} - -std::optional GaussianBlurFilterContents::GetFilterSourceCoverage( - const Matrix& effect_transform, - const Rect& output_limit) const { - Scalar blur_radius = CalculateBlurRadius(sigma_); - Vector3 blur_radii = - effect_transform.Basis() * Vector3{blur_radius, blur_radius, 0.0}; - return output_limit.Expand(Point(blur_radii.x, blur_radii.y)); -} - -std::optional GaussianBlurFilterContents::GetFilterCoverage( - const FilterInput::Vector& inputs, - const Entity& entity, - const Matrix& effect_transform) const { - if (inputs.empty()) { - return {}; - } - - std::optional input_coverage = inputs[0]->GetCoverage(entity); - if (!input_coverage.has_value()) { - return {}; - } - - Scalar blur_radius = CalculateBlurRadius(sigma_); - Vector3 blur_radii = - effect_transform.Basis() * Vector3{blur_radius, blur_radius, 0.0}; - return input_coverage.value().Expand(Point(blur_radii.x, blur_radii.y)); -} - -std::optional GaussianBlurFilterContents::RenderFilter( - const FilterInput::Vector& input_textures, - const ContentContext& renderer, - const Entity& entity, - const Matrix& effect_transform, - const Rect& coverage, - const std::optional& coverage_hint) const { - return {}; -} - -Scalar GaussianBlurFilterContents::CalculateBlurRadius(Scalar sigma) { - return static_cast(Sigma(sigma)).radius; -} - -} // namespace impeller diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.h b/impeller/entity/contents/filters/gaussian_blur_filter_contents.h deleted file mode 100644 index 68ee98e8d18f1..0000000000000 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.h +++ /dev/null @@ -1,48 +0,0 @@ -// 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. - -#pragma once - -#include -#include "impeller/entity/contents/filters/filter_contents.h" - -namespace impeller { - -/// Performs a bidirectional Gaussian blur. -/// -/// This is accomplished by rendering multiple passes in multiple directions. -/// Note: This will replace `DirectionalGaussianBlurFilterContents`. -class GaussianBlurFilterContents final : public FilterContents { - public: - GaussianBlurFilterContents(Scalar sigma = 0.0f); - - Scalar GetSigma() const { return sigma_; } - - // |FilterContents| - std::optional GetFilterSourceCoverage( - const Matrix& effect_transform, - const Rect& output_limit) const override; - - // |FilterContents| - std::optional GetFilterCoverage( - const FilterInput::Vector& inputs, - const Entity& entity, - const Matrix& effect_transform) const override; - - static Scalar CalculateBlurRadius(Scalar sigma); - - private: - // |FilterContents| - std::optional RenderFilter( - const FilterInput::Vector& input_textures, - const ContentContext& renderer, - const Entity& entity, - const Matrix& effect_transform, - const Rect& coverage, - const std::optional& coverage_hint) const override; - - const Scalar sigma_ = 0.0; -}; - -} // namespace impeller diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc deleted file mode 100644 index 9e308ee4820ac..0000000000000 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc +++ /dev/null @@ -1,100 +0,0 @@ -// 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/testing/testing.h" -#include "gmock/gmock.h" -#include "impeller/entity/contents/filters/gaussian_blur_filter_contents.h" -#include "impeller/renderer/testing/mocks.h" - -namespace impeller { -namespace testing { - -using ::testing::Return; - -namespace { - -Scalar CalculateSigmaForBlurRadius(Scalar blur_radius) { - // See Sigma.h - return (blur_radius / kKernelRadiusPerSigma) + 0.5; -} -} // namespace - -TEST(GaussianBlurFilterContents, Create) { - GaussianBlurFilterContents contents; - ASSERT_EQ(contents.GetSigma(), 0.0); -} - -TEST(GaussianBlurFilterContents, CoverageEmpty) { - GaussianBlurFilterContents contents; - FilterInput::Vector inputs = {}; - Entity entity; - std::optional coverage = - contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix()); - ASSERT_FALSE(coverage.has_value()); -} - -TEST(GaussianBlurFilterContents, CoverageSimple) { - GaussianBlurFilterContents contents; - FilterInput::Vector inputs = { - FilterInput::Make(Rect::MakeLTRB(10, 10, 110, 110))}; - Entity entity; - std::optional coverage = - contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix()); - ASSERT_EQ(coverage, Rect::MakeLTRB(10, 10, 110, 110)); -} - -TEST(GaussianBlurFilterContents, CoverageWithSigma) { - Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); - GaussianBlurFilterContents contents(/*sigma=*/sigma_radius_1); - FilterInput::Vector inputs = { - FilterInput::Make(Rect::MakeLTRB(100, 100, 200, 200))}; - Entity entity; - std::optional coverage = - contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix()); - ASSERT_EQ(coverage, Rect::MakeLTRB(99, 99, 201, 201)); -} - -TEST(GaussianBlurFilterContents, CoverageWithTexture) { - TextureDescriptor desc = { - .size = ISize(100, 100), - }; - Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); - GaussianBlurFilterContents contents(/*sigma=*/sigma_radius_1); - std::shared_ptr texture = std::make_shared(desc); - EXPECT_CALL(*texture, GetSize()).WillRepeatedly(Return(ISize(100, 100))); - FilterInput::Vector inputs = {FilterInput::Make(texture)}; - Entity entity; - entity.SetTransformation(Matrix::MakeTranslation({100, 100, 0})); - std::optional coverage = - contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix()); - ASSERT_EQ(coverage, Rect::MakeLTRB(99, 99, 201, 201)); -} - -TEST(GaussianBlurFilterContents, CoverageWithEffectTransform) { - TextureDescriptor desc = { - .size = ISize(100, 100), - }; - Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); - GaussianBlurFilterContents contents(/*sigma=*/sigma_radius_1); - std::shared_ptr texture = std::make_shared(desc); - EXPECT_CALL(*texture, GetSize()).WillRepeatedly(Return(ISize(100, 100))); - FilterInput::Vector inputs = {FilterInput::Make(texture)}; - Entity entity; - entity.SetTransformation(Matrix::MakeTranslation({100, 100, 0})); - std::optional coverage = contents.GetFilterCoverage( - inputs, entity, /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0})); - ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2)); -} - -TEST(GaussianBlurFilterContents, FilterSourceCoverage) { - Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); - auto contents = std::make_unique(sigma_radius_1); - std::optional coverage = contents->GetFilterSourceCoverage( - /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}), - /*output_limit=*/Rect::MakeLTRB(100, 100, 200, 200)); - ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2)); -} - -} // namespace testing -} // namespace impeller diff --git a/impeller/renderer/testing/mocks.h b/impeller/renderer/testing/mocks.h index 5d6ae779926a7..15c8ae8ef86e4 100644 --- a/impeller/renderer/testing/mocks.h +++ b/impeller/renderer/testing/mocks.h @@ -197,6 +197,7 @@ class MockRenderTargetAllocator : public RenderTargetAllocator { class MockCapabilities : public Capabilities { public: MOCK_METHOD(bool, SupportsOffscreenMSAA, (), (const, override)); + MOCK_METHOD(bool, SupportsImplicitResolvingMSAA, (), (const, override)); MOCK_METHOD(bool, SupportsSSBO, (), (const, override)); MOCK_METHOD(bool, SupportsBufferToTextureBlits, (), (const, override)); MOCK_METHOD(bool, SupportsTextureToTextureBlits, (), (const, override)); From 33c3faf33f3af52cb820f1039461720899045dfd Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 3 Nov 2023 13:19:08 -0700 Subject: [PATCH 09/17] license --- ci/licenses_golden/excluded_files | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index b50f836af1bcf..7e136992a25a2 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -135,6 +135,7 @@ ../../../flutter/impeller/display_list/skia_conversions_unittests.cc ../../../flutter/impeller/docs ../../../flutter/impeller/entity/contents/checkerboard_contents_unittests.cc +../../../flutter/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc ../../../flutter/impeller/entity/contents/filters/inputs/filter_input_unittests.cc ../../../flutter/impeller/entity/entity_unittests.cc ../../../flutter/impeller/entity/geometry/geometry_unittests.cc From 05711b8d6f86919c87b8c9d4beefb8b862158943 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 3 Nov 2023 14:04:41 -0700 Subject: [PATCH 10/17] moved to entityplayground --- ...gaussian_blur_filter_contents_unittests.cc | 139 ++++-------------- 1 file changed, 32 insertions(+), 107 deletions(-) diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc index c567eb810564c..22d1ea5422898 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -6,16 +6,13 @@ #include "gmock/gmock.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.h" +#include "impeller/entity/entity_playground.h" #include "impeller/renderer/testing/mocks.h" namespace impeller { namespace testing { -using ::testing::_; -using ::testing::An; -using ::testing::Invoke; using ::testing::Return; -using ::testing::ReturnRef; namespace { @@ -25,112 +22,45 @@ Scalar CalculateSigmaForBlurRadius(Scalar blur_radius) { } } // namespace -class DirectionalGaussianBlurFilterContentsTest : public ::testing::Test { +class DirectionalGaussianBlurFilterContentsTest : public EntityPlayground { public: - void SetUp() override { - mock_render_target_allocator_ = - std::make_shared(mock_allocator_); - capabilities_ = mock_capabilities_; - } - // Stubs in the minimal support to make rendering pass. - void SetupMinimalContext() { - EXPECT_CALL(*mock_context_, GetCapabilities()) - .WillRepeatedly(ReturnRef(capabilities_)); - EXPECT_CALL(*mock_context_, IsValid()).WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_pipeline_library_, GetPipeline(An())) - .WillRepeatedly(Invoke([mock_pipeline_library = - std::weak_ptr( - mock_pipeline_library_)]( - PipelineDescriptor descriptor) { - PipelineFuture result; - std::promise>> promise; - auto mock_pipeline = - std::make_shared>( - mock_pipeline_library, descriptor); - EXPECT_CALL(*mock_pipeline, IsValid()).WillRepeatedly(Return(true)); - promise.set_value(mock_pipeline); - result.descriptor = descriptor; - result.future = promise.get_future(); - return result; - })); - EXPECT_CALL(*mock_shader_library_, GetFunction(_, _)) - .WillRepeatedly(Invoke([](std::string_view name, ShaderStage stage) { - return std::make_shared(UniqueID(), - std::string(name), stage); - })); - EXPECT_CALL(*mock_context_, GetSamplerLibrary()) - .WillRepeatedly(Return(mock_sampler_library_)); - EXPECT_CALL(*mock_context_, GetShaderLibrary()) - .WillRepeatedly(Return(mock_shader_library_)); - EXPECT_CALL(*mock_context_, GetPipelineLibrary()) - .WillRepeatedly(Return(mock_pipeline_library_)); - EXPECT_CALL(*mock_context_, CreateCommandBuffer()) - .WillRepeatedly(Invoke(([mock_context = - std::weak_ptr( - mock_context_)]() { - auto result = std::make_shared(mock_context); - EXPECT_CALL(*result, IsValid()).WillRepeatedly(Return(true)); - EXPECT_CALL(*result, OnSubmitCommands(_)) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*result, OnCreateRenderPass(_)) - .WillRepeatedly( - Invoke(([mock_context](const RenderTarget& render_target) { - auto result = std::make_shared( - mock_context, render_target); - EXPECT_CALL(*result, IsValid).WillRepeatedly(Return(true)); - EXPECT_CALL(*result, OnEncodeCommands(_)) - .WillRepeatedly(Return(true)); - return result; - }))); - return result; - }))); - EXPECT_CALL(*mock_render_target_allocator_, CreateTexture(_)) - .WillRepeatedly(Invoke(([](const TextureDescriptor& desc) { - auto result = std::make_shared(desc); - EXPECT_CALL(*result, IsValid()).WillRepeatedly(Return(true)); - EXPECT_CALL(*result, GetSize()).WillRepeatedly(Return(desc.size)); - return result; - }))); + void SetupMinimalMockContext() { + // This mocking code was removed since it wasn't strictly needed yet. If it + // is needed you can find it here: + // https://gist.github.com/gaaclarke/c2f6bf5fc6ecb10678da03789abc5843. } - - std::shared_ptr mock_context_ = - std::make_shared(); - std::shared_ptr mock_capabilities_ = - std::make_shared(); - std::shared_ptr mock_sampler_library_ = - std::make_shared(); - std::shared_ptr mock_shader_library_ = - std::make_shared(); - std::shared_ptr mock_pipeline_library_ = - std::make_shared(); - std::shared_ptr mock_typographer_context_ = - std::make_shared(); - std::shared_ptr mock_allocator_ = - std::make_shared(); - std::shared_ptr mock_render_target_allocator_; - std::shared_ptr capabilities_; }; -TEST_F(DirectionalGaussianBlurFilterContentsTest, CoverageWithEffectTransform) { +INSTANTIATE_PLAYGROUND_SUITE(DirectionalGaussianBlurFilterContentsTest); + +TEST_P(DirectionalGaussianBlurFilterContentsTest, CoverageWithEffectTransform) { TextureDescriptor desc = { + .format = PixelFormat::kB8G8R8A8UNormInt, .size = ISize(100, 100), }; Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); auto contents = std::make_unique(); contents->SetSigma(Sigma{sigma_radius_1}); contents->SetDirection({1.0, 0.0}); - std::shared_ptr texture = std::make_shared(desc); - EXPECT_CALL(*texture, GetSize()).WillRepeatedly(Return(ISize(100, 100))); + std::shared_ptr texture = + GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture( + desc); FilterInput::Vector inputs = {FilterInput::Make(texture)}; Entity entity; entity.SetTransformation(Matrix::MakeTranslation({100, 100, 0})); std::optional coverage = contents->GetFilterCoverage( inputs, entity, /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0})); - ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100, 200 + 2, 200)); + ASSERT_TRUE(coverage.has_value()); + EXPECT_NEAR(coverage->GetLeft(), 100 - 2, + 0.5); // Higher tolerance for sigma scaling. + EXPECT_NEAR(coverage->GetTop(), 100, 0.01); + EXPECT_NEAR(coverage->GetRight(), 200 + 2, + 0.5); // Higher tolerance for sigma scaling. + EXPECT_NEAR(coverage->GetBottom(), 200, 0.01); } -TEST_F(DirectionalGaussianBlurFilterContentsTest, FilterSourceCoverage) { +TEST(DirectionalGaussianBlurFilterContentsTest, FilterSourceCoverage) { Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); auto contents = std::make_unique(); contents->SetSigma(Sigma{sigma_radius_1}); @@ -141,42 +71,37 @@ TEST_F(DirectionalGaussianBlurFilterContentsTest, FilterSourceCoverage) { ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100, 200 + 2, 200)); } -TEST_F(DirectionalGaussianBlurFilterContentsTest, RenderNoCoverage) { +TEST_P(DirectionalGaussianBlurFilterContentsTest, RenderNoCoverage) { Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); auto contents = std::make_unique(); contents->SetSigma(Sigma{sigma_radius_1}); contents->SetDirection({1.0, 0.0}); - auto mock_context = std::make_shared(); - auto mock_typographer_context = std::make_shared(); - auto mock_allocator = std::make_shared(); - auto mock_render_target_allocator = - std::make_shared(mock_allocator); - ContentContext renderer(mock_context, mock_typographer_context, - mock_render_target_allocator); + std::shared_ptr renderer = GetContentContext(); Entity entity; Rect coverage_hint = Rect::MakeLTRB(0, 0, 0, 0); std::optional result = - contents->GetEntity(renderer, entity, coverage_hint); + contents->GetEntity(*renderer, entity, coverage_hint); ASSERT_FALSE(result.has_value()); } -TEST_F(DirectionalGaussianBlurFilterContentsTest, RenderSomething) { - SetupMinimalContext(); +TEST_P(DirectionalGaussianBlurFilterContentsTest, RenderSomething) { TextureDescriptor desc = { + .format = PixelFormat::kB8G8R8A8UNormInt, .size = ISize(100, 100), }; - std::shared_ptr texture = std::make_shared(desc); - EXPECT_CALL(*texture, GetSize()).WillRepeatedly(Return(ISize(100, 100))); + std::shared_ptr texture = + GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture( + desc); Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0); auto contents = std::make_unique(); contents->SetSigma(Sigma{sigma_radius_1}); contents->SetDirection({1.0, 0.0}); contents->SetInputs({FilterInput::Make(texture)}); - ContentContext renderer(mock_context_, mock_typographer_context_, - mock_render_target_allocator_); + std::shared_ptr renderer = GetContentContext(); + Entity entity; std::optional result = - contents->GetEntity(renderer, entity, /*coverage_hint=*/{}); + contents->GetEntity(*renderer, entity, /*coverage_hint=*/{}); ASSERT_TRUE(result.has_value()); EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver); std::optional result_coverage = result.value().GetCoverage(); From 9bade3dfc26d99b2a5c17dbe5603ef1aa098d11b Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 3 Nov 2023 14:25:30 -0700 Subject: [PATCH 11/17] renamed test --- .../directional_gaussian_blur_filter_contents_unittests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc index 22d1ea5422898..306711dfb8d46 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -84,7 +84,7 @@ TEST_P(DirectionalGaussianBlurFilterContentsTest, RenderNoCoverage) { ASSERT_FALSE(result.has_value()); } -TEST_P(DirectionalGaussianBlurFilterContentsTest, RenderSomething) { +TEST_P(DirectionalGaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverage) { TextureDescriptor desc = { .format = PixelFormat::kB8G8R8A8UNormInt, .size = ISize(100, 100), From d46a8916cb037680a7157dea4e8a8b40399d1fd3 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 3 Nov 2023 14:38:30 -0700 Subject: [PATCH 12/17] license --- ci/licenses_golden/licenses_flutter | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index ef656b3972b56..7ed7a51cbc2db 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -3058,8 +3058,6 @@ ORIGIN: ../../../flutter/impeller/entity/contents/filters/directional_gaussian_b ORIGIN: ../../../flutter/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/contents/filters/filter_contents.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/contents/filters/filter_contents.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/contents_filter_input.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/contents_filter_input.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc + ../../../flutter/LICENSE @@ -5843,8 +5841,6 @@ FILE: ../../../flutter/impeller/entity/contents/filters/directional_gaussian_blu FILE: ../../../flutter/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.h FILE: ../../../flutter/impeller/entity/contents/filters/filter_contents.cc FILE: ../../../flutter/impeller/entity/contents/filters/filter_contents.h -FILE: ../../../flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc -FILE: ../../../flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents.h FILE: ../../../flutter/impeller/entity/contents/filters/inputs/contents_filter_input.cc FILE: ../../../flutter/impeller/entity/contents/filters/inputs/contents_filter_input.h FILE: ../../../flutter/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc From 6017a65786fd2113b314cb9885fdd6c78f2c51d8 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 3 Nov 2023 14:42:10 -0700 Subject: [PATCH 13/17] lint fix --- ...gaussian_blur_filter_contents_unittests.cc | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc index 306711dfb8d46..d32c542d26003 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -51,13 +51,15 @@ TEST_P(DirectionalGaussianBlurFilterContentsTest, CoverageWithEffectTransform) { entity.SetTransformation(Matrix::MakeTranslation({100, 100, 0})); std::optional coverage = contents->GetFilterCoverage( inputs, entity, /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0})); - ASSERT_TRUE(coverage.has_value()); - EXPECT_NEAR(coverage->GetLeft(), 100 - 2, - 0.5); // Higher tolerance for sigma scaling. - EXPECT_NEAR(coverage->GetTop(), 100, 0.01); - EXPECT_NEAR(coverage->GetRight(), 200 + 2, - 0.5); // Higher tolerance for sigma scaling. - EXPECT_NEAR(coverage->GetBottom(), 200, 0.01); + EXPECT_TRUE(coverage.has_value()); + if (coverage.has_value()) { + EXPECT_NEAR(coverage->GetLeft(), 100 - 2, + 0.5); // Higher tolerance for sigma scaling. + EXPECT_NEAR(coverage->GetTop(), 100, 0.01); + EXPECT_NEAR(coverage->GetRight(), 200 + 2, + 0.5); // Higher tolerance for sigma scaling. + EXPECT_NEAR(coverage->GetBottom(), 200, 0.01); + } } TEST(DirectionalGaussianBlurFilterContentsTest, FilterSourceCoverage) { @@ -84,7 +86,8 @@ TEST_P(DirectionalGaussianBlurFilterContentsTest, RenderNoCoverage) { ASSERT_FALSE(result.has_value()); } -TEST_P(DirectionalGaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverage) { +TEST_P(DirectionalGaussianBlurFilterContentsTest, + RenderCoverageMatchesGetCoverage) { TextureDescriptor desc = { .format = PixelFormat::kB8G8R8A8UNormInt, .size = ISize(100, 100), @@ -108,14 +111,16 @@ TEST_P(DirectionalGaussianBlurFilterContentsTest, RenderCoverageMatchesGetCovera std::optional contents_coverage = contents->GetCoverage(entity); EXPECT_TRUE(result_coverage.has_value()); EXPECT_TRUE(contents_coverage.has_value()); - EXPECT_NEAR(result_coverage.value().GetLeft(), - contents_coverage.value().GetLeft(), kEhCloseEnough); - EXPECT_NEAR(result_coverage.value().GetTop(), - contents_coverage.value().GetTop(), kEhCloseEnough); - EXPECT_NEAR(result_coverage.value().GetRight(), - contents_coverage.value().GetRight(), kEhCloseEnough); - EXPECT_NEAR(result_coverage.value().GetBottom(), - contents_coverage.value().GetBottom(), kEhCloseEnough); + if (result_coverage.has_value() && contents_coverage.has_value()) { + EXPECT_NEAR(result_coverage.value().GetLeft(), + contents_coverage.value().GetLeft(), kEhCloseEnough); + EXPECT_NEAR(result_coverage.value().GetTop(), + contents_coverage.value().GetTop(), kEhCloseEnough); + EXPECT_NEAR(result_coverage.value().GetRight(), + contents_coverage.value().GetRight(), kEhCloseEnough); + EXPECT_NEAR(result_coverage.value().GetBottom(), + contents_coverage.value().GetBottom(), kEhCloseEnough); + } } } // namespace testing From 19f738160539fe0c157ca6c6eda4467a67ab266d Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 3 Nov 2023 15:00:59 -0700 Subject: [PATCH 14/17] tidy --- .../directional_gaussian_blur_filter_contents_unittests.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc index d32c542d26003..532fb0ae534c3 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -105,8 +105,10 @@ TEST_P(DirectionalGaussianBlurFilterContentsTest, Entity entity; std::optional result = contents->GetEntity(*renderer, entity, /*coverage_hint=*/{}); - ASSERT_TRUE(result.has_value()); - EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver); + EXPECT_TRUE(result.has_value()); + if (result.has_value()) { + EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver); + } std::optional result_coverage = result.value().GetCoverage(); std::optional contents_coverage = contents->GetCoverage(entity); EXPECT_TRUE(result_coverage.has_value()); From a2b886858566563069812de58a2c0e6abfc0ceb0 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 6 Nov 2023 09:06:53 -0800 Subject: [PATCH 15/17] lint --- ...gaussian_blur_filter_contents_unittests.cc | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc index 532fb0ae534c3..67ce67d83e7e8 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -108,20 +108,20 @@ TEST_P(DirectionalGaussianBlurFilterContentsTest, EXPECT_TRUE(result.has_value()); if (result.has_value()) { EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver); - } - std::optional result_coverage = result.value().GetCoverage(); - std::optional contents_coverage = contents->GetCoverage(entity); - EXPECT_TRUE(result_coverage.has_value()); - EXPECT_TRUE(contents_coverage.has_value()); - if (result_coverage.has_value() && contents_coverage.has_value()) { - EXPECT_NEAR(result_coverage.value().GetLeft(), - contents_coverage.value().GetLeft(), kEhCloseEnough); - EXPECT_NEAR(result_coverage.value().GetTop(), - contents_coverage.value().GetTop(), kEhCloseEnough); - EXPECT_NEAR(result_coverage.value().GetRight(), - contents_coverage.value().GetRight(), kEhCloseEnough); - EXPECT_NEAR(result_coverage.value().GetBottom(), - contents_coverage.value().GetBottom(), kEhCloseEnough); + std::optional result_coverage = result.value().GetCoverage(); + std::optional contents_coverage = contents->GetCoverage(entity); + EXPECT_TRUE(result_coverage.has_value()); + EXPECT_TRUE(contents_coverage.has_value()); + if (contents_coverage.has_value()) { + EXPECT_NEAR(result_coverage.value().GetLeft(), + contents_coverage.value().GetLeft(), kEhCloseEnough); + EXPECT_NEAR(result_coverage.value().GetTop(), + contents_coverage.value().GetTop(), kEhCloseEnough); + EXPECT_NEAR(result_coverage.value().GetRight(), + contents_coverage.value().GetRight(), kEhCloseEnough); + EXPECT_NEAR(result_coverage.value().GetBottom(), + contents_coverage.value().GetBottom(), kEhCloseEnough); + } } } From f46ff8c24429e5c8ef999c0b3a035dcf83b3f35b Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 6 Nov 2023 10:42:14 -0800 Subject: [PATCH 16/17] lint, sorry really should have checked these locally --- .../directional_gaussian_blur_filter_contents_unittests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc index 67ce67d83e7e8..cfe98445adaf4 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc @@ -112,7 +112,7 @@ TEST_P(DirectionalGaussianBlurFilterContentsTest, std::optional contents_coverage = contents->GetCoverage(entity); EXPECT_TRUE(result_coverage.has_value()); EXPECT_TRUE(contents_coverage.has_value()); - if (contents_coverage.has_value()) { + if (result_coverage.has_value() && contents_coverage.has_value()) { EXPECT_NEAR(result_coverage.value().GetLeft(), contents_coverage.value().GetLeft(), kEhCloseEnough); EXPECT_NEAR(result_coverage.value().GetTop(), From 20f2fc8865481ab77b69329b5c865b27fac14c93 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 6 Nov 2023 10:49:20 -0800 Subject: [PATCH 17/17] removed mocks --- impeller/renderer/testing/mocks.h | 113 ------------------------------ 1 file changed, 113 deletions(-) diff --git a/impeller/renderer/testing/mocks.h b/impeller/renderer/testing/mocks.h index 15c8ae8ef86e4..8d50ac115c27b 100644 --- a/impeller/renderer/testing/mocks.h +++ b/impeller/renderer/testing/mocks.h @@ -9,12 +9,7 @@ #include "impeller/core/texture.h" #include "impeller/renderer/command_buffer.h" #include "impeller/renderer/context.h" -#include "impeller/renderer/pipeline_library.h" -#include "impeller/renderer/render_pass.h" #include "impeller/renderer/render_target.h" -#include "impeller/renderer/sampler_library.h" -#include "impeller/renderer/shader_function.h" -#include "impeller/typographer/typographer_context.h" namespace impeller { namespace testing { @@ -169,113 +164,5 @@ class MockTexture : public Texture { (override)); }; -class MockTypographerContext : public TypographerContext { - public: - MOCK_METHOD(std::shared_ptr, - CreateGlyphAtlas, - (Context & context, - GlyphAtlas::Type type, - std::shared_ptr atlas_context, - const FontGlyphMap& font_glyph_map), - (const, override)); - MOCK_METHOD(std::shared_ptr, - CreateGlyphAtlasContext, - (), - (const, override)); -}; - -class MockRenderTargetAllocator : public RenderTargetAllocator { - public: - MockRenderTargetAllocator(std::shared_ptr allocator) - : RenderTargetAllocator(allocator) {} - MOCK_METHOD(std::shared_ptr, - CreateTexture, - (const TextureDescriptor& desc), - (override)); -}; - -class MockCapabilities : public Capabilities { - public: - MOCK_METHOD(bool, SupportsOffscreenMSAA, (), (const, override)); - MOCK_METHOD(bool, SupportsImplicitResolvingMSAA, (), (const, override)); - MOCK_METHOD(bool, SupportsSSBO, (), (const, override)); - MOCK_METHOD(bool, SupportsBufferToTextureBlits, (), (const, override)); - MOCK_METHOD(bool, SupportsTextureToTextureBlits, (), (const, override)); - MOCK_METHOD(bool, SupportsFramebufferFetch, (), (const, override)); - MOCK_METHOD(bool, SupportsCompute, (), (const, override)); - MOCK_METHOD(bool, SupportsComputeSubgroups, (), (const, override)); - MOCK_METHOD(bool, SupportsReadFromOnscreenTexture, (), (const, override)); - MOCK_METHOD(bool, SupportsReadFromResolve, (), (const, override)); - MOCK_METHOD(bool, SupportsDecalSamplerAddressMode, (), (const, override)); - MOCK_METHOD(bool, SupportsDeviceTransientTextures, (), (const, override)); - MOCK_METHOD(PixelFormat, GetDefaultColorFormat, (), (const, override)); - MOCK_METHOD(PixelFormat, GetDefaultStencilFormat, (), (const, override)); - MOCK_METHOD(PixelFormat, GetDefaultDepthStencilFormat, (), (const, override)); -}; - -class MockRenderPass : public RenderPass { - public: - MockRenderPass(std::weak_ptr context, - const RenderTarget& target) - : RenderPass(context, target) {} - MOCK_METHOD(bool, IsValid, (), (const, override)); - MOCK_METHOD(void, OnSetLabel, (std::string), (override)); - MOCK_METHOD(bool, OnEncodeCommands, (const Context&), (const, override)); -}; - -class MockSamplerLibrary : public SamplerLibrary { - public: - MOCK_METHOD(std::shared_ptr, - GetSampler, - (SamplerDescriptor), - (override)); -}; - -class MockShaderLibrary : public ShaderLibrary { - public: - MOCK_METHOD(bool, IsValid, (), (const, override)); - MOCK_METHOD(std::shared_ptr, - GetFunction, - (std::string_view name, ShaderStage stage), - (override)); - MOCK_METHOD(void, - UnregisterFunction, - (std::string name, ShaderStage stage), - (override)); -}; - -class MockShaderFunction : public ShaderFunction { - public: - MockShaderFunction(UniqueID parent_library_id, - std::string name, - ShaderStage stage) - : ShaderFunction(parent_library_id, name, stage) {} -}; - -class MockPipelineLibrary : public PipelineLibrary { - public: - MOCK_METHOD(bool, IsValid, (), (const, override)); - MOCK_METHOD(PipelineFuture, - GetPipeline, - (PipelineDescriptor descriptor), - (override)); - MOCK_METHOD(PipelineFuture, - GetPipeline, - (ComputePipelineDescriptor descriptor), - (override)); - MOCK_METHOD(void, - RemovePipelinesWithEntryPoint, - (std::shared_ptr function), - (override)); -}; - -template -class MockPipeline : public Pipeline { - public: - MockPipeline(std::weak_ptr library, T desc) - : Pipeline(library, desc) {} - MOCK_METHOD(bool, IsValid, (), (const, override)); -}; - } // namespace testing } // namespace impeller