Flutter Impeller
matrix_filter_contents.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 namespace impeller {
8 
10 
12 
14  matrix_ = matrix;
15 }
16 
18  Entity::RenderingMode rendering_mode) {
19  rendering_mode_ = rendering_mode;
20  FilterContents::SetRenderingMode(rendering_mode);
21 }
22 
24  return matrix_.Basis().IsIdentity() && FilterContents::IsTranslationOnly();
25 }
26 
28  sampler_descriptor_ = std::move(desc);
29 }
30 
31 std::optional<Entity> MatrixFilterContents::RenderFilter(
32  const FilterInput::Vector& inputs,
33  const ContentContext& renderer,
34  const Entity& entity,
35  const Matrix& effect_transform,
36  const Rect& coverage,
37  const std::optional<Rect>& coverage_hint) const {
38  auto snapshot = inputs[0]->GetSnapshot("Matrix", renderer, entity);
39  if (!snapshot.has_value()) {
40  return std::nullopt;
41  }
42 
43  // The filter's matrix needs to be applied within the space defined by the
44  // scene's current transform matrix (CTM). For example: If the CTM is
45  // scaled up, then translations applied by the matrix should be magnified
46  // accordingly.
47  //
48  // To accomplish this, we sandwich the filter's matrix within the CTM in both
49  // cases. But notice that for the subpass backdrop filter case, we use the
50  // "effect transform" instead of the Entity's transform!
51  //
52  // That's because in the subpass backdrop filter case, the Entity's transform
53  // isn't actually the captured CTM of the scene like it usually is; instead,
54  // it's just a screen space translation that offsets the backdrop texture (as
55  // mentioned above). And so we sneak the subpass's captured CTM in through the
56  // effect transform.
57 
58  auto transform = rendering_mode_ == Entity::RenderingMode::kSubpass
59  ? effect_transform
60  : entity.GetTransform();
61  snapshot->transform = transform * //
62  matrix_ * //
63  transform.Invert() * //
64  snapshot->transform;
65 
66  snapshot->sampler_descriptor = sampler_descriptor_;
67  if (!snapshot.has_value()) {
68  return std::nullopt;
69  }
70  return Entity::FromSnapshot(snapshot.value(), entity.GetBlendMode(),
71  entity.GetClipDepth());
72 }
73 
74 std::optional<Rect> MatrixFilterContents::GetFilterSourceCoverage(
75  const Matrix& effect_transform,
76  const Rect& output_limit) const {
77  auto transform = effect_transform * //
78  matrix_ * //
79  effect_transform.Invert(); //
80  if (transform.GetDeterminant() == 0.0) {
81  return std::nullopt;
82  }
83  auto inverse = transform.Invert();
84  return output_limit.TransformBounds(inverse);
85 }
86 
88  const FilterInput::Vector& inputs,
89  const Entity& entity,
90  const Matrix& effect_transform) const {
91  if (inputs.empty()) {
92  return std::nullopt;
93  }
94 
95  auto coverage = inputs[0]->GetCoverage(entity);
96  if (!coverage.has_value()) {
97  return std::nullopt;
98  }
99  auto& m = rendering_mode_ == Entity::RenderingMode::kSubpass
100  ? effect_transform
101  : inputs[0]->GetTransform(entity);
102  auto transform = m * //
103  matrix_ * //
104  m.Invert(); //
105  return coverage->TransformBounds(transform);
106 }
107 
108 } // namespace impeller
impeller::MatrixFilterContents::SetRenderingMode
void SetRenderingMode(Entity::RenderingMode rendering_mode) override
Marks this filter chain as applying in a subpass scenario.
Definition: matrix_filter_contents.cc:17
impeller::Entity::GetTransform
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:49
impeller::MatrixFilterContents::SetMatrix
void SetMatrix(Matrix matrix)
Definition: matrix_filter_contents.cc:13
impeller::TRect::TransformBounds
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:405
impeller::Entity::FromSnapshot
static Entity FromSnapshot(const Snapshot &snapshot, BlendMode blend_mode=BlendMode::kSourceOver, uint32_t clip_depth=0)
Create an entity that can be used to render a given snapshot.
Definition: entity.cc:22
impeller::SamplerDescriptor
Definition: sampler_descriptor.h:15
impeller::Entity
Definition: entity.h:21
impeller::Matrix::Basis
constexpr Matrix Basis() const
The Matrix without its w components (without translation).
Definition: matrix.h:224
impeller::MatrixFilterContents::~MatrixFilterContents
~MatrixFilterContents() override
impeller::FilterContents::IsTranslationOnly
virtual bool IsTranslationOnly() const
Returns true if this filter graph doesn't perform any basis transforms to the filtered content....
Definition: filter_contents.cc:279
matrix_filter_contents.h
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:661
impeller::Entity::RenderingMode::kSubpass
@ kSubpass
impeller::Entity::GetBlendMode
BlendMode GetBlendMode() const
Definition: entity.cc:134
impeller::Matrix::Invert
Matrix Invert() const
Definition: matrix.cc:97
impeller::Matrix::IsIdentity
constexpr bool IsIdentity() const
Definition: matrix.h:350
impeller::Entity::GetClipDepth
uint32_t GetClipDepth() const
Definition: entity.cc:105
impeller::MatrixFilterContents::MatrixFilterContents
MatrixFilterContents()
impeller::FilterContents::SetRenderingMode
virtual void SetRenderingMode(Entity::RenderingMode rendering_mode)
Marks this filter chain as applying in a subpass scenario.
Definition: filter_contents.cc:307
impeller::Entity::RenderingMode
RenderingMode
Definition: entity.h:28
impeller::MatrixFilterContents::GetFilterCoverage
std::optional< Rect > GetFilterCoverage(const FilterInput::Vector &inputs, const Entity &entity, const Matrix &effect_transform) const override
Internal utility method for |GetLocalCoverage| that computes the output coverage of this filter acros...
Definition: matrix_filter_contents.cc:87
impeller::FilterInput::Vector
std::vector< FilterInput::Ref > Vector
Definition: filter_input.h:33
impeller::MatrixFilterContents::IsTranslationOnly
bool IsTranslationOnly() const override
Returns true if this filter graph doesn't perform any basis transforms to the filtered content....
Definition: matrix_filter_contents.cc:23
impeller
Definition: aiks_blur_unittests.cc:20
impeller::MatrixFilterContents::SetSamplerDescriptor
void SetSamplerDescriptor(SamplerDescriptor desc)
Definition: matrix_filter_contents.cc:27
impeller::ContentContext
Definition: content_context.h:392
impeller::TRect
Definition: rect.h:122
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37