From 1a096635f486a6793e771d3bd8a72858dc03fcc4 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 13 Sep 2023 09:56:54 -0700 Subject: [PATCH 1/2] [Impeller] Incorporate filters in subpass coverage. --- impeller/aiks/aiks_unittests.cc | 4 +- impeller/aiks/paint.cc | 17 +++++--- impeller/aiks/paint.h | 9 ++-- impeller/aiks/paint_pass_delegate.cc | 14 ++++++ impeller/aiks/paint_pass_delegate.h | 10 +++++ impeller/entity/contents/contents.cc | 4 ++ impeller/entity/contents/contents.h | 7 +++ .../contents/filters/filter_contents.cc | 12 ++++++ .../entity/contents/filters/filter_contents.h | 12 ++++++ .../inputs/filter_contents_filter_input.cc | 4 ++ .../inputs/filter_contents_filter_input.h | 3 ++ .../contents/filters/inputs/filter_input.cc | 4 ++ .../contents/filters/inputs/filter_input.h | 3 ++ .../filters/matrix_filter_contents.cc | 5 +++ .../contents/filters/matrix_filter_contents.h | 3 ++ impeller/entity/entity_pass.cc | 43 +++++++++++++++++-- impeller/entity/entity_pass.h | 3 ++ impeller/entity/entity_pass_delegate.cc | 7 +++ impeller/entity/entity_pass_delegate.h | 6 +++ impeller/entity/entity_unittests.cc | 7 +++ 20 files changed, 163 insertions(+), 14 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 3438056a0b6a9..74807ad2a593a 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -3173,7 +3173,7 @@ TEST_P(AiksTest, MatrixSaveLayerFilter) { canvas.SaveLayer({.image_filter = ImageFilter::MakeMatrix( Matrix::MakeTranslation(Vector2(1, 1) * (200 + 100 * k1OverSqrt2)) * - Matrix::MakeScale(Vector2(1, 1) * 0.2) * + Matrix::MakeScale(Vector2(1, 1) * 0.5) * Matrix::MakeTranslation(Vector2(-200, -200)), SamplerDescriptor{})}, std::nullopt); @@ -3201,7 +3201,7 @@ TEST_P(AiksTest, MatrixBackdropFilter) { {}, std::nullopt, ImageFilter::MakeMatrix( Matrix::MakeTranslation(Vector2(1, 1) * (100 + 100 * k1OverSqrt2)) * - Matrix::MakeScale(Vector2(1, 1) * 0.2) * + Matrix::MakeScale(Vector2(1, 1) * 0.5) * Matrix::MakeTranslation(Vector2(-100, -100)), SamplerDescriptor{})); canvas.Restore(); diff --git a/impeller/aiks/paint.cc b/impeller/aiks/paint.cc index a7bb6d00d3152..5c2b808c69eb3 100644 --- a/impeller/aiks/paint.cc +++ b/impeller/aiks/paint.cc @@ -60,14 +60,21 @@ std::shared_ptr Paint::WithFilters( std::shared_ptr input) const { input = WithColorFilter(input, /*absorb_opacity=*/true); input = WithInvertFilter(input); - input = WithImageFilter(input, Matrix(), /*is_subpass=*/false); + auto image_filter = WithImageFilter(input, Matrix(), /*is_subpass=*/false); + if (image_filter) { + input = image_filter; + } return input; } std::shared_ptr Paint::WithFiltersForSubpassTarget( std::shared_ptr input, const Matrix& effect_transform) const { - input = WithImageFilter(input, effect_transform, /*is_subpass=*/true); + auto image_filter = + WithImageFilter(input, effect_transform, /*is_subpass=*/true); + if (image_filter) { + input = image_filter; + } input = WithColorFilter(input, /*absorb_opacity=*/true); return input; } @@ -81,12 +88,12 @@ std::shared_ptr Paint::WithMaskBlur(std::shared_ptr input, return input; } -std::shared_ptr Paint::WithImageFilter( - std::shared_ptr input, +std::shared_ptr Paint::WithImageFilter( + const FilterInput::Variant& input, const Matrix& effect_transform, bool is_subpass) const { if (!image_filter) { - return input; + return nullptr; } auto filter = image_filter->WrapInput(FilterInput::Make(input)); filter->SetIsForSubpass(is_subpass); diff --git a/impeller/aiks/paint.h b/impeller/aiks/paint.h index d77a298d5bd21..384b4bdb1f150 100644 --- a/impeller/aiks/paint.h +++ b/impeller/aiks/paint.h @@ -98,11 +98,12 @@ struct Paint { std::shared_ptr WithMaskBlur(std::shared_ptr input, bool is_solid_color) const; - private: - std::shared_ptr WithImageFilter(std::shared_ptr input, - const Matrix& effect_transform, - bool is_subpass) const; + std::shared_ptr WithImageFilter( + const FilterInput::Variant& input, + const Matrix& effect_transform, + bool is_subpass) const; + private: std::shared_ptr WithColorFilter(std::shared_ptr input, bool absorb_opacity = false) const; diff --git a/impeller/aiks/paint_pass_delegate.cc b/impeller/aiks/paint_pass_delegate.cc index 382ca3457cd93..6a72338028d5a 100644 --- a/impeller/aiks/paint_pass_delegate.cc +++ b/impeller/aiks/paint_pass_delegate.cc @@ -47,6 +47,13 @@ std::shared_ptr PaintPassDelegate::CreateContentsForSubpassTarget( effect_transform); } +// |EntityPassDelgate| +std::shared_ptr PaintPassDelegate::WithImageFilter( + const FilterInput::Variant& input, + const Matrix& effect_transform) const { + return paint_.WithImageFilter(input, effect_transform, true); +} + /// OpacityPeepholePassDelegate /// ---------------------------------------------- @@ -140,4 +147,11 @@ OpacityPeepholePassDelegate::CreateContentsForSubpassTarget( effect_transform); } +// |EntityPassDelgate| +std::shared_ptr OpacityPeepholePassDelegate::WithImageFilter( + const FilterInput::Variant& input, + const Matrix& effect_transform) const { + return paint_.WithImageFilter(input, effect_transform, true); +} + } // namespace impeller diff --git a/impeller/aiks/paint_pass_delegate.h b/impeller/aiks/paint_pass_delegate.h index 967b59ea81e63..17e87b20bd366 100644 --- a/impeller/aiks/paint_pass_delegate.h +++ b/impeller/aiks/paint_pass_delegate.h @@ -32,6 +32,11 @@ class PaintPassDelegate final : public EntityPassDelegate { std::shared_ptr target, const Matrix& effect_transform) override; + // |EntityPassDelgate| + std::shared_ptr WithImageFilter( + const FilterInput::Variant& input, + const Matrix& effect_transform) const override; + private: const Paint paint_; @@ -61,6 +66,11 @@ class OpacityPeepholePassDelegate final : public EntityPassDelegate { std::shared_ptr target, const Matrix& effect_transform) override; + // |EntityPassDelgate| + std::shared_ptr WithImageFilter( + const FilterInput::Variant& input, + const Matrix& effect_transform) const override; + private: const Paint paint_; diff --git a/impeller/entity/contents/contents.cc b/impeller/entity/contents/contents.cc index 85e70e534e061..a181e22302b21 100644 --- a/impeller/entity/contents/contents.cc +++ b/impeller/entity/contents/contents.cc @@ -123,6 +123,10 @@ std::optional Contents::AsBackgroundColor(const Entity& entity, return {}; } +const FilterContents* Contents::AsFilter() const { + return nullptr; +} + bool Contents::ApplyColorFilter( const Contents::ColorFilterProc& color_filter_proc) { return false; diff --git a/impeller/entity/contents/contents.h b/impeller/entity/contents/contents.h index 245b8f2d6d514..b9dec5db2d12e 100644 --- a/impeller/entity/contents/contents.h +++ b/impeller/entity/contents/contents.h @@ -23,6 +23,7 @@ struct ContentContextOptions; class Entity; class Surface; class RenderPass; +class FilterContents; ContentContextOptions OptionsFromPass(const RenderPass& pass); @@ -155,6 +156,12 @@ class Contents { virtual std::optional AsBackgroundColor(const Entity& entity, ISize target_size) const; + //---------------------------------------------------------------------------- + /// @brief Cast to a filter. Returns `nullptr` if this Contents is not a + /// filter. + /// + virtual const FilterContents* AsFilter() const; + //---------------------------------------------------------------------------- /// @brief If possible, applies a color filter to this contents inputs on /// the CPU. diff --git a/impeller/entity/contents/filters/filter_contents.cc b/impeller/entity/contents/filters/filter_contents.cc index ae48cec892ddc..c606ad8ec43d2 100644 --- a/impeller/entity/contents/filters/filter_contents.cc +++ b/impeller/entity/contents/filters/filter_contents.cc @@ -259,6 +259,10 @@ std::optional FilterContents::RenderToSnapshot( return std::nullopt; } +const FilterContents* FilterContents::AsFilter() const { + return this; +} + Matrix FilterContents::GetLocalTransform(const Matrix& parent_transform) const { return Matrix(); } @@ -266,6 +270,14 @@ Matrix FilterContents::GetLocalTransform(const Matrix& parent_transform) const { Matrix FilterContents::GetTransform(const Matrix& parent_transform) const { return parent_transform * GetLocalTransform(parent_transform); } +bool FilterContents::HasBasisTransformations() const { + for (auto& input : inputs_) { + if (!input->HasBasisTransformations()) { + return false; + } + } + return true; +} bool FilterContents::IsLeaf() const { for (auto& input : inputs_) { diff --git a/impeller/entity/contents/filters/filter_contents.h b/impeller/entity/contents/filters/filter_contents.h index e5e7604434821..79fb4a3c40e6d 100644 --- a/impeller/entity/contents/filters/filter_contents.h +++ b/impeller/entity/contents/filters/filter_contents.h @@ -125,10 +125,22 @@ class FilterContents : public Contents { bool msaa_enabled = true, const std::string& label = "Filter Snapshot") const override; + // |Contents| + const FilterContents* AsFilter() const override; + virtual Matrix GetLocalTransform(const Matrix& parent_transform) const; Matrix GetTransform(const Matrix& parent_transform) const; + /// @brief Returns true of this filter graph performs basis transformations + /// to the filtered content. For example: Rotating, scaling, and + /// skewing are all basis transformations, but translating is not. + /// + /// This is useful for determining whether a filtered object's space + /// is compatible enough with the parent pass space to perform certain + /// subpass optimizations. + virtual bool HasBasisTransformations() const; + /// @brief Returns `true` if this filter does not have any `FilterInput` /// children. bool IsLeaf() const; diff --git a/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc b/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc index e1af31f8bede4..83205650e2bfd 100644 --- a/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc +++ b/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc @@ -58,6 +58,10 @@ void FilterContentsFilterInput::PopulateGlyphAtlas( filter_->PopulateGlyphAtlas(lazy_glyph_atlas, scale); } +bool FilterContentsFilterInput::HasBasisTransformations() const { + return filter_->HasBasisTransformations(); +} + bool FilterContentsFilterInput::IsLeaf() const { return false; } diff --git a/impeller/entity/contents/filters/inputs/filter_contents_filter_input.h b/impeller/entity/contents/filters/inputs/filter_contents_filter_input.h index 7aaaa3aebdd7a..9a79d7ef6b1c5 100644 --- a/impeller/entity/contents/filters/inputs/filter_contents_filter_input.h +++ b/impeller/entity/contents/filters/inputs/filter_contents_filter_input.h @@ -36,6 +36,9 @@ class FilterContentsFilterInput final : public FilterInput { const std::shared_ptr& lazy_glyph_atlas, Scalar scale) override; + // |FilterInput| + bool HasBasisTransformations() const override; + // |FilterInput| bool IsLeaf() const override; diff --git a/impeller/entity/contents/filters/inputs/filter_input.cc b/impeller/entity/contents/filters/inputs/filter_input.cc index 1cb4744468c20..de2a4420f1953 100644 --- a/impeller/entity/contents/filters/inputs/filter_input.cc +++ b/impeller/entity/contents/filters/inputs/filter_input.cc @@ -76,6 +76,10 @@ void FilterInput::PopulateGlyphAtlas( FilterInput::~FilterInput() = default; +bool FilterInput::HasBasisTransformations() const { + return false; +} + bool FilterInput::IsLeaf() const { return true; } diff --git a/impeller/entity/contents/filters/inputs/filter_input.h b/impeller/entity/contents/filters/inputs/filter_input.h index 598ca1b560cca..6fdf0dd2c7812 100644 --- a/impeller/entity/contents/filters/inputs/filter_input.h +++ b/impeller/entity/contents/filters/inputs/filter_input.h @@ -69,6 +69,9 @@ class FilterInput { const std::shared_ptr& lazy_glyph_atlas, Scalar scale); + /// @see `FilterContents::HasBasisTransformations` + virtual bool HasBasisTransformations() const; + /// @brief Returns `true` unless this input is a `FilterInput`, which may /// take other inputs. virtual bool IsLeaf() const; diff --git a/impeller/entity/contents/filters/matrix_filter_contents.cc b/impeller/entity/contents/filters/matrix_filter_contents.cc index 5483b4d7d306b..d7385b95b6744 100644 --- a/impeller/entity/contents/filters/matrix_filter_contents.cc +++ b/impeller/entity/contents/filters/matrix_filter_contents.cc @@ -19,6 +19,11 @@ void MatrixFilterContents::SetIsForSubpass(bool is_subpass) { FilterContents::SetIsForSubpass(is_subpass); } +bool MatrixFilterContents::HasBasisTransformations() const { + return !matrix_.Basis().IsIdentity() || + FilterContents::HasBasisTransformations(); +} + void MatrixFilterContents::SetSamplerDescriptor(SamplerDescriptor desc) { sampler_descriptor_ = std::move(desc); } diff --git a/impeller/entity/contents/filters/matrix_filter_contents.h b/impeller/entity/contents/filters/matrix_filter_contents.h index a2e4c5f239953..585e39ec23b88 100644 --- a/impeller/entity/contents/filters/matrix_filter_contents.h +++ b/impeller/entity/contents/filters/matrix_filter_contents.h @@ -20,6 +20,9 @@ class MatrixFilterContents final : public FilterContents { // |FilterContents| void SetIsForSubpass(bool is_for_subpass) override; + // |FilterContents| + bool HasBasisTransformations() const override; + void SetSamplerDescriptor(SamplerDescriptor desc); // |FilterContents| diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index 29a737e8f57e5..81db8cef76fe0 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -110,12 +110,39 @@ std::optional EntityPass::GetElementsCoverage( if (auto entity = std::get_if(&element)) { coverage = entity->GetCoverage(); + // When the coverage limit is std::nullopt, that means there is no limit, + // as opposed to empty coverage. if (coverage.has_value() && coverage_limit.has_value()) { - coverage = coverage->Intersection(coverage_limit.value()); + const auto* filter = entity->GetContents()->AsFilter(); + if (!filter || !filter->HasBasisTransformations()) { + coverage = coverage->Intersection(coverage_limit.value()); + } } - } else if (auto subpass = + } else if (auto subpass_ptr = std::get_if>(&element)) { - coverage = GetSubpassCoverage(*subpass->get(), coverage_limit); + auto& subpass = *subpass_ptr->get(); + + std::optional unfiltered_coverage = + GetSubpassCoverage(subpass, std::nullopt); + if (!unfiltered_coverage.has_value()) { + continue; + } + + std::shared_ptr image_filter = + subpass.delegate_->WithImageFilter(*unfiltered_coverage, + subpass.xformation_); + if (image_filter) { + Entity subpass_entity; + subpass_entity.SetTransformation(subpass.xformation_); + coverage = image_filter->GetCoverage(subpass_entity); + } else { + coverage = unfiltered_coverage; + } + + if (coverage.has_value() && coverage_limit.has_value() && + (!image_filter || !image_filter->HasBasisTransformations())) { + coverage = coverage->Intersection(coverage_limit.value()); + } } else { FML_UNREACHABLE(); } @@ -135,6 +162,16 @@ std::optional EntityPass::GetElementsCoverage( std::optional EntityPass::GetSubpassCoverage( const EntityPass& subpass, std::optional coverage_limit) const { + std::shared_ptr image_filter = + subpass.delegate_->WithImageFilter(Rect(), subpass.xformation_); + + // If the filter graph transforms the basis of the subpass, then its space + // has deviated too much from the parent pass to safely intersect with the + // pass coverage limit. + coverage_limit = (image_filter && image_filter->HasBasisTransformations() + ? std::nullopt + : coverage_limit); + auto entities_coverage = subpass.GetElementsCoverage(coverage_limit); // The entities don't cover anything. There is nothing to do. if (!entities_coverage.has_value()) { diff --git a/impeller/entity/entity_pass.h b/impeller/entity/entity_pass.h index f9b11d155f50f..f00c9d3653978 100644 --- a/impeller/entity/entity_pass.h +++ b/impeller/entity/entity_pass.h @@ -141,6 +141,9 @@ class EntityPass { void SetEnableOffscreenCheckerboard(bool enabled); + //---------------------------------------------------------------------------- + /// @brief Get the coverage of an unfiltered subpass. + /// std::optional GetSubpassCoverage( const EntityPass& subpass, std::optional coverage_limit) const; diff --git a/impeller/entity/entity_pass_delegate.cc b/impeller/entity/entity_pass_delegate.cc index b996995b57de6..e6a1021956176 100644 --- a/impeller/entity/entity_pass_delegate.cc +++ b/impeller/entity/entity_pass_delegate.cc @@ -34,6 +34,13 @@ class DefaultEntityPassDelegate final : public EntityPassDelegate { FML_UNREACHABLE(); } + // |EntityPassDelgate| + std::shared_ptr WithImageFilter( + const FilterInput::Variant& input, + const Matrix& effect_transform) const override { + return nullptr; + } + private: FML_DISALLOW_COPY_AND_ASSIGN(DefaultEntityPassDelegate); }; diff --git a/impeller/entity/entity_pass_delegate.h b/impeller/entity/entity_pass_delegate.h index fbc7f97be2bbb..4675236b35a79 100644 --- a/impeller/entity/entity_pass_delegate.h +++ b/impeller/entity/entity_pass_delegate.h @@ -9,6 +9,8 @@ #include "flutter/fml/macros.h" #include "impeller/core/texture.h" #include "impeller/entity/contents/contents.h" +#include "impeller/entity/contents/filters/filter_contents.h" +#include "impeller/entity/contents/filters/inputs/filter_input.h" namespace impeller { @@ -32,6 +34,10 @@ class EntityPassDelegate { std::shared_ptr target, const Matrix& effect_transform) = 0; + virtual std::shared_ptr WithImageFilter( + const FilterInput::Variant& input, + const Matrix& effect_transform) const = 0; + private: FML_DISALLOW_COPY_AND_ASSIGN(EntityPassDelegate); }; diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index b5d36ca2abad8..3ff5548509b5e 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -91,6 +91,13 @@ class TestPassDelegate final : public EntityPassDelegate { return nullptr; } + // |EntityPassDelegate| + std::shared_ptr WithImageFilter( + const FilterInput::Variant& input, + const Matrix& effect_transform) const override { + return nullptr; + } + private: const std::optional coverage_; const bool collapse_; From 61d37465670b1cbad32f1ac0b499e94d8039a0e4 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 13 Sep 2023 12:15:55 -0700 Subject: [PATCH 2/2] Address comments --- impeller/entity/contents/filters/filter_contents.cc | 4 ++-- impeller/entity/contents/filters/filter_contents.h | 11 ++++++----- .../filters/inputs/filter_contents_filter_input.cc | 4 ++-- .../filters/inputs/filter_contents_filter_input.h | 2 +- .../entity/contents/filters/inputs/filter_input.cc | 4 ++-- .../entity/contents/filters/inputs/filter_input.h | 2 +- .../entity/contents/filters/matrix_filter_contents.cc | 5 ++--- .../entity/contents/filters/matrix_filter_contents.h | 2 +- impeller/entity/entity_pass.cc | 10 +++++----- 9 files changed, 22 insertions(+), 22 deletions(-) diff --git a/impeller/entity/contents/filters/filter_contents.cc b/impeller/entity/contents/filters/filter_contents.cc index c606ad8ec43d2..3d4fa96a6321b 100644 --- a/impeller/entity/contents/filters/filter_contents.cc +++ b/impeller/entity/contents/filters/filter_contents.cc @@ -270,9 +270,9 @@ Matrix FilterContents::GetLocalTransform(const Matrix& parent_transform) const { Matrix FilterContents::GetTransform(const Matrix& parent_transform) const { return parent_transform * GetLocalTransform(parent_transform); } -bool FilterContents::HasBasisTransformations() const { +bool FilterContents::IsTranslationOnly() const { for (auto& input : inputs_) { - if (!input->HasBasisTransformations()) { + if (!input->IsTranslationOnly()) { return false; } } diff --git a/impeller/entity/contents/filters/filter_contents.h b/impeller/entity/contents/filters/filter_contents.h index 79fb4a3c40e6d..c14393444980c 100644 --- a/impeller/entity/contents/filters/filter_contents.h +++ b/impeller/entity/contents/filters/filter_contents.h @@ -132,14 +132,15 @@ class FilterContents : public Contents { Matrix GetTransform(const Matrix& parent_transform) const; - /// @brief Returns true of this filter graph performs basis transformations - /// to the filtered content. For example: Rotating, scaling, and - /// skewing are all basis transformations, but translating is not. + /// @brief Returns true if this filter graph doesn't perform any basis + /// transformations to the filtered content. For example: Rotating, + /// scaling, and skewing are all basis transformations, but + /// translating is not. /// /// This is useful for determining whether a filtered object's space /// is compatible enough with the parent pass space to perform certain - /// subpass optimizations. - virtual bool HasBasisTransformations() const; + /// subpass clipping optimizations. + virtual bool IsTranslationOnly() const; /// @brief Returns `true` if this filter does not have any `FilterInput` /// children. diff --git a/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc b/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc index 83205650e2bfd..78a1cec98e3b2 100644 --- a/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc +++ b/impeller/entity/contents/filters/inputs/filter_contents_filter_input.cc @@ -58,8 +58,8 @@ void FilterContentsFilterInput::PopulateGlyphAtlas( filter_->PopulateGlyphAtlas(lazy_glyph_atlas, scale); } -bool FilterContentsFilterInput::HasBasisTransformations() const { - return filter_->HasBasisTransformations(); +bool FilterContentsFilterInput::IsTranslationOnly() const { + return filter_->IsTranslationOnly(); } bool FilterContentsFilterInput::IsLeaf() const { diff --git a/impeller/entity/contents/filters/inputs/filter_contents_filter_input.h b/impeller/entity/contents/filters/inputs/filter_contents_filter_input.h index 9a79d7ef6b1c5..45d44993520cf 100644 --- a/impeller/entity/contents/filters/inputs/filter_contents_filter_input.h +++ b/impeller/entity/contents/filters/inputs/filter_contents_filter_input.h @@ -37,7 +37,7 @@ class FilterContentsFilterInput final : public FilterInput { Scalar scale) override; // |FilterInput| - bool HasBasisTransformations() const override; + bool IsTranslationOnly() const override; // |FilterInput| bool IsLeaf() const override; diff --git a/impeller/entity/contents/filters/inputs/filter_input.cc b/impeller/entity/contents/filters/inputs/filter_input.cc index de2a4420f1953..e438212688a44 100644 --- a/impeller/entity/contents/filters/inputs/filter_input.cc +++ b/impeller/entity/contents/filters/inputs/filter_input.cc @@ -76,8 +76,8 @@ void FilterInput::PopulateGlyphAtlas( FilterInput::~FilterInput() = default; -bool FilterInput::HasBasisTransformations() const { - return false; +bool FilterInput::IsTranslationOnly() const { + return true; } bool FilterInput::IsLeaf() const { diff --git a/impeller/entity/contents/filters/inputs/filter_input.h b/impeller/entity/contents/filters/inputs/filter_input.h index 6fdf0dd2c7812..43db41eb6a8ef 100644 --- a/impeller/entity/contents/filters/inputs/filter_input.h +++ b/impeller/entity/contents/filters/inputs/filter_input.h @@ -70,7 +70,7 @@ class FilterInput { Scalar scale); /// @see `FilterContents::HasBasisTransformations` - virtual bool HasBasisTransformations() const; + virtual bool IsTranslationOnly() const; /// @brief Returns `true` unless this input is a `FilterInput`, which may /// take other inputs. diff --git a/impeller/entity/contents/filters/matrix_filter_contents.cc b/impeller/entity/contents/filters/matrix_filter_contents.cc index d7385b95b6744..c767ffe6cd19f 100644 --- a/impeller/entity/contents/filters/matrix_filter_contents.cc +++ b/impeller/entity/contents/filters/matrix_filter_contents.cc @@ -19,9 +19,8 @@ void MatrixFilterContents::SetIsForSubpass(bool is_subpass) { FilterContents::SetIsForSubpass(is_subpass); } -bool MatrixFilterContents::HasBasisTransformations() const { - return !matrix_.Basis().IsIdentity() || - FilterContents::HasBasisTransformations(); +bool MatrixFilterContents::IsTranslationOnly() const { + return matrix_.Basis().IsIdentity() && FilterContents::IsTranslationOnly(); } void MatrixFilterContents::SetSamplerDescriptor(SamplerDescriptor desc) { diff --git a/impeller/entity/contents/filters/matrix_filter_contents.h b/impeller/entity/contents/filters/matrix_filter_contents.h index 585e39ec23b88..ea221301d8e33 100644 --- a/impeller/entity/contents/filters/matrix_filter_contents.h +++ b/impeller/entity/contents/filters/matrix_filter_contents.h @@ -21,7 +21,7 @@ class MatrixFilterContents final : public FilterContents { void SetIsForSubpass(bool is_for_subpass) override; // |FilterContents| - bool HasBasisTransformations() const override; + bool IsTranslationOnly() const override; void SetSamplerDescriptor(SamplerDescriptor desc); diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index 81db8cef76fe0..b93d997d468d2 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -114,7 +114,7 @@ std::optional EntityPass::GetElementsCoverage( // as opposed to empty coverage. if (coverage.has_value() && coverage_limit.has_value()) { const auto* filter = entity->GetContents()->AsFilter(); - if (!filter || !filter->HasBasisTransformations()) { + if (!filter || filter->IsTranslationOnly()) { coverage = coverage->Intersection(coverage_limit.value()); } } @@ -140,7 +140,7 @@ std::optional EntityPass::GetElementsCoverage( } if (coverage.has_value() && coverage_limit.has_value() && - (!image_filter || !image_filter->HasBasisTransformations())) { + (!image_filter || image_filter->IsTranslationOnly())) { coverage = coverage->Intersection(coverage_limit.value()); } } else { @@ -168,9 +168,9 @@ std::optional EntityPass::GetSubpassCoverage( // If the filter graph transforms the basis of the subpass, then its space // has deviated too much from the parent pass to safely intersect with the // pass coverage limit. - coverage_limit = (image_filter && image_filter->HasBasisTransformations() - ? std::nullopt - : coverage_limit); + coverage_limit = + (image_filter && image_filter->IsTranslationOnly() ? std::nullopt + : coverage_limit); auto entities_coverage = subpass.GetElementsCoverage(coverage_limit); // The entities don't cover anything. There is nothing to do.