mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Add placeholder filter input. (flutter/engine#44290)
This is a revival of my patch to add the necessary mechanisms for: https://github.com/flutter/flutter/issues/131632 ... since it turns out we need it sooner than later for https://github.com/flutter/flutter/issues/131182.
This commit is contained in:
parent
0f472bdf48
commit
5b6a8bc86f
@ -1201,6 +1201,8 @@ ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/filter_contents
|
||||
ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/filter_contents_filter_input.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/filter_input.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/filter_input.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/placeholder_filter_input.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/placeholder_filter_input.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/texture_filter_input.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/contents/filters/inputs/texture_filter_input.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/contents/filters/linear_to_srgb_filter_contents.cc + ../../../flutter/LICENSE
|
||||
@ -3903,6 +3905,8 @@ FILE: ../../../flutter/impeller/entity/contents/filters/inputs/filter_contents_f
|
||||
FILE: ../../../flutter/impeller/entity/contents/filters/inputs/filter_contents_filter_input.h
|
||||
FILE: ../../../flutter/impeller/entity/contents/filters/inputs/filter_input.cc
|
||||
FILE: ../../../flutter/impeller/entity/contents/filters/inputs/filter_input.h
|
||||
FILE: ../../../flutter/impeller/entity/contents/filters/inputs/placeholder_filter_input.cc
|
||||
FILE: ../../../flutter/impeller/entity/contents/filters/inputs/placeholder_filter_input.h
|
||||
FILE: ../../../flutter/impeller/entity/contents/filters/inputs/texture_filter_input.cc
|
||||
FILE: ../../../flutter/impeller/entity/contents/filters/inputs/texture_filter_input.h
|
||||
FILE: ../../../flutter/impeller/entity/contents/filters/linear_to_srgb_filter_contents.cc
|
||||
|
||||
@ -175,6 +175,8 @@ impeller_component("entity") {
|
||||
"contents/filters/inputs/filter_contents_filter_input.h",
|
||||
"contents/filters/inputs/filter_input.cc",
|
||||
"contents/filters/inputs/filter_input.h",
|
||||
"contents/filters/inputs/placeholder_filter_input.cc",
|
||||
"contents/filters/inputs/placeholder_filter_input.h",
|
||||
"contents/filters/inputs/texture_filter_input.cc",
|
||||
"contents/filters/inputs/texture_filter_input.h",
|
||||
"contents/filters/linear_to_srgb_filter_contents.cc",
|
||||
|
||||
@ -277,4 +277,23 @@ Matrix FilterContents::GetTransform(const Matrix& parent_transform) const {
|
||||
return parent_transform * GetLocalTransform(parent_transform);
|
||||
}
|
||||
|
||||
bool FilterContents::IsLeaf() const {
|
||||
for (auto& input : inputs_) {
|
||||
if (!input->IsLeaf()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FilterContents::SetLeafInputs(const FilterInput::Vector& inputs) {
|
||||
if (IsLeaf()) {
|
||||
inputs_ = inputs;
|
||||
return;
|
||||
}
|
||||
for (auto& input : inputs_) {
|
||||
input->SetLeafInputs(inputs);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -133,6 +133,15 @@ class FilterContents : public Contents {
|
||||
|
||||
Matrix GetTransform(const Matrix& parent_transform) const;
|
||||
|
||||
/// @brief Returns `true` if this filter does not have any `FilterInput`
|
||||
/// children.
|
||||
bool IsLeaf() const;
|
||||
|
||||
/// @brief Replaces the leaf of all leaf `FilterContents` with a new set
|
||||
/// of `inputs`.
|
||||
/// @see `FilterContents::IsLeaf`
|
||||
void SetLeafInputs(const FilterInput::Vector& inputs);
|
||||
|
||||
private:
|
||||
virtual std::optional<Rect> GetFilterCoverage(
|
||||
const FilterInput::Vector& inputs,
|
||||
|
||||
@ -58,4 +58,13 @@ void FilterContentsFilterInput::PopulateGlyphAtlas(
|
||||
filter_->PopulateGlyphAtlas(lazy_glyph_atlas, scale);
|
||||
}
|
||||
|
||||
bool FilterContentsFilterInput::IsLeaf() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void FilterContentsFilterInput::SetLeafInputs(
|
||||
const FilterInput::Vector& inputs) {
|
||||
filter_->SetLeafInputs(inputs);
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -36,8 +36,14 @@ class FilterContentsFilterInput final : public FilterInput {
|
||||
const std::shared_ptr<LazyGlyphAtlas>& lazy_glyph_atlas,
|
||||
Scalar scale) override;
|
||||
|
||||
// |FilterInput|
|
||||
bool IsLeaf() const override;
|
||||
|
||||
// |FilterInput|
|
||||
void SetLeafInputs(const FilterInput::Vector& inputs) override;
|
||||
|
||||
private:
|
||||
FilterContentsFilterInput(std::shared_ptr<FilterContents> filter);
|
||||
explicit FilterContentsFilterInput(std::shared_ptr<FilterContents> filter);
|
||||
|
||||
std::shared_ptr<FilterContents> filter_;
|
||||
mutable std::optional<Snapshot> snapshot_;
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "impeller/entity/contents/filters/filter_contents.h"
|
||||
#include "impeller/entity/contents/filters/inputs/contents_filter_input.h"
|
||||
#include "impeller/entity/contents/filters/inputs/filter_contents_filter_input.h"
|
||||
#include "impeller/entity/contents/filters/inputs/placeholder_filter_input.h"
|
||||
#include "impeller/entity/contents/filters/inputs/texture_filter_input.h"
|
||||
|
||||
namespace impeller {
|
||||
@ -32,6 +33,11 @@ FilterInput::Ref FilterInput::Make(Variant input, bool msaa_enabled) {
|
||||
return Make(*texture, Matrix());
|
||||
}
|
||||
|
||||
if (auto rect = std::get_if<Rect>(&input)) {
|
||||
return std::shared_ptr<PlaceholderFilterInput>(
|
||||
new PlaceholderFilterInput(*rect));
|
||||
}
|
||||
|
||||
FML_UNREACHABLE();
|
||||
}
|
||||
|
||||
@ -70,4 +76,10 @@ void FilterInput::PopulateGlyphAtlas(
|
||||
|
||||
FilterInput::~FilterInput() = default;
|
||||
|
||||
bool FilterInput::IsLeaf() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void FilterInput::SetLeafInputs(const FilterInput::Vector& inputs) {}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -32,7 +32,8 @@ class FilterInput {
|
||||
using Vector = std::vector<FilterInput::Ref>;
|
||||
using Variant = std::variant<std::shared_ptr<FilterContents>,
|
||||
std::shared_ptr<Contents>,
|
||||
std::shared_ptr<Texture>>;
|
||||
std::shared_ptr<Texture>,
|
||||
Rect>;
|
||||
|
||||
virtual ~FilterInput();
|
||||
|
||||
@ -67,6 +68,15 @@ class FilterInput {
|
||||
virtual void PopulateGlyphAtlas(
|
||||
const std::shared_ptr<LazyGlyphAtlas>& lazy_glyph_atlas,
|
||||
Scalar scale);
|
||||
|
||||
/// @brief Returns `true` unless this input is a `FilterInput`, which may
|
||||
/// take other inputs.
|
||||
virtual bool IsLeaf() const;
|
||||
|
||||
/// @brief Replaces the inputs of all leaf `FilterContents` with a new set
|
||||
/// of `inputs`.
|
||||
/// @see `FilterInput::IsLeaf`
|
||||
virtual void SetLeafInputs(const FilterInput::Vector& inputs);
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -5,8 +5,10 @@
|
||||
#include <memory>
|
||||
#include "flutter/testing/testing.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "impeller/entity/contents/filters/color_filter_contents.h"
|
||||
#include "impeller/entity/contents/filters/inputs/filter_input.h"
|
||||
#include "impeller/entity/entity.h"
|
||||
#include "impeller/geometry/color.h"
|
||||
#include "impeller/geometry/geometry_asserts.h"
|
||||
|
||||
namespace impeller {
|
||||
@ -25,5 +27,41 @@ TEST(FilterInputTest, CanSetLocalTransformForTexture) {
|
||||
Matrix::MakeTranslation({1.0, 2.0, 0.0}));
|
||||
}
|
||||
|
||||
TEST(FilterInputTest, IsLeaf) {
|
||||
std::shared_ptr<FilterContents> leaf =
|
||||
ColorFilterContents::MakeBlend(BlendMode::kSource, {});
|
||||
ASSERT_TRUE(leaf->IsLeaf());
|
||||
|
||||
auto base = ColorFilterContents::MakeMatrixFilter(
|
||||
FilterInput::Make(leaf), Matrix(), {}, Matrix(), false);
|
||||
|
||||
ASSERT_TRUE(leaf->IsLeaf());
|
||||
ASSERT_FALSE(base->IsLeaf());
|
||||
}
|
||||
|
||||
TEST(FilterInputTest, SetCoverageInputs) {
|
||||
std::shared_ptr<FilterContents> leaf =
|
||||
ColorFilterContents::MakeBlend(BlendMode::kSource, {});
|
||||
ASSERT_TRUE(leaf->IsLeaf());
|
||||
|
||||
auto base = ColorFilterContents::MakeMatrixFilter(
|
||||
FilterInput::Make(leaf), Matrix(), {}, Matrix(), false);
|
||||
|
||||
{
|
||||
auto result = base->GetCoverage({});
|
||||
ASSERT_FALSE(result.has_value());
|
||||
}
|
||||
|
||||
auto coverage_rect = Rect::MakeLTRB(100, 100, 200, 200);
|
||||
base->SetLeafInputs(FilterInput::Make({coverage_rect}));
|
||||
|
||||
{
|
||||
auto result = base->GetCoverage({});
|
||||
ASSERT_TRUE(result.has_value());
|
||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||
ASSERT_RECT_NEAR(result.value(), coverage_rect);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace impeller
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
// 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/inputs/placeholder_filter_input.h"
|
||||
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include "impeller/base/strings.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
PlaceholderFilterInput::PlaceholderFilterInput(Rect coverage_rect)
|
||||
: coverage_rect_(coverage_rect) {}
|
||||
|
||||
PlaceholderFilterInput::~PlaceholderFilterInput() = default;
|
||||
|
||||
FilterInput::Variant PlaceholderFilterInput::GetInput() const {
|
||||
return coverage_rect_;
|
||||
}
|
||||
|
||||
std::optional<Snapshot> PlaceholderFilterInput::GetSnapshot(
|
||||
const std::string& label,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
std::optional<Rect> coverage_limit) const {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Rect> PlaceholderFilterInput::GetCoverage(
|
||||
const Entity& entity) const {
|
||||
return coverage_rect_;
|
||||
}
|
||||
|
||||
void PlaceholderFilterInput::PopulateGlyphAtlas(
|
||||
const std::shared_ptr<LazyGlyphAtlas>& lazy_glyph_atlas,
|
||||
Scalar scale) {}
|
||||
|
||||
} // namespace impeller
|
||||
@ -0,0 +1,41 @@
|
||||
// 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 "impeller/entity/contents/filters/inputs/filter_input.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
class PlaceholderFilterInput final : public FilterInput {
|
||||
public:
|
||||
explicit PlaceholderFilterInput(Rect coverage);
|
||||
|
||||
~PlaceholderFilterInput() override;
|
||||
|
||||
// |FilterInput|
|
||||
Variant GetInput() const override;
|
||||
|
||||
// |FilterInput|
|
||||
std::optional<Snapshot> GetSnapshot(
|
||||
const std::string& label,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
std::optional<Rect> coverage_limit) const override;
|
||||
|
||||
// |FilterInput|
|
||||
std::optional<Rect> GetCoverage(const Entity& entity) const override;
|
||||
|
||||
// |FilterInput|
|
||||
void PopulateGlyphAtlas(
|
||||
const std::shared_ptr<LazyGlyphAtlas>& lazy_glyph_atlas,
|
||||
Scalar scale) override;
|
||||
|
||||
private:
|
||||
Rect coverage_rect_;
|
||||
|
||||
friend FilterInput;
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
Loading…
x
Reference in New Issue
Block a user