Flutter Engine
The Flutter Engine
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
7namespace impeller {
8
10
12
14 matrix_ = matrix;
15}
16
18 Entity::RenderingMode rendering_mode) {
19 rendering_mode_ = rendering_mode;
21}
22
25}
26
28 sampler_descriptor_ = std::move(desc);
29}
30
31namespace {
32Matrix CalculateSubpassTransform(const Matrix& snapshot_transform,
33 const Matrix& effect_transform,
34 const Matrix& matrix,
35 Entity::RenderingMode rendering_mode) {
36 if (rendering_mode ==
38 return snapshot_transform * //
39 effect_transform * //
40 matrix * //
41 effect_transform.Invert();
42 } else {
43 FML_DCHECK(rendering_mode ==
45 return effect_transform * //
46 matrix * //
47 effect_transform.Invert() * //
48 snapshot_transform;
49 }
50}
51} // namespace
52
53std::optional<Entity> MatrixFilterContents::RenderFilter(
55 const ContentContext& renderer,
56 const Entity& entity,
57 const Matrix& effect_transform,
58 const Rect& coverage,
59 const std::optional<Rect>& coverage_hint) const {
60 auto snapshot = inputs[0]->GetSnapshot("Matrix", renderer, entity);
61 if (!snapshot.has_value()) {
62 return std::nullopt;
63 }
64
65 if (rendering_mode_ ==
67 rendering_mode_ ==
69 // There are two special quirks with how Matrix filters behave when used as
70 // subpass backdrop filters:
71 //
72 // 1. For subpass backdrop filters, the snapshot transform is always just a
73 // translation that positions the parent pass texture correctly relative
74 // to the subpass texture. However, this translation always needs to be
75 // applied in screen space.
76 //
77 // Since we know the snapshot transform will always have an identity
78 // basis in this case, we safely reverse the order and apply the filter's
79 // matrix within the snapshot transform space.
80 //
81 // 2. The filter's matrix needs to be applied within the space defined by
82 // the scene's current transformation matrix (CTM). For example: If the
83 // CTM is scaled up, then translations applied by the matrix should be
84 // magnified accordingly.
85 //
86 // To accomplish this, we sandwitch the filter's matrix within the CTM in
87 // both cases. But notice that for the subpass backdrop filter case, we
88 // use the "effect transform" instead of the Entity's transform!
89 //
90 // That's because in the subpass backdrop filter case, the Entity's
91 // transform isn't actually the captured CTM of the scene like it usually
92 // is; instead, it's just a screen space translation that offsets the
93 // backdrop texture (as mentioned above). And so we sneak the subpass's
94 // captured CTM in through the effect transform.
95 //
96 snapshot->transform = CalculateSubpassTransform(
97 snapshot->transform, effect_transform, matrix_, rendering_mode_);
98 } else {
99 snapshot->transform = entity.GetTransform() * //
100 matrix_ * //
101 entity.GetTransform().Invert() * //
102 snapshot->transform;
103 }
104 snapshot->sampler_descriptor = sampler_descriptor_;
105 if (!snapshot.has_value()) {
106 return std::nullopt;
107 }
108 return Entity::FromSnapshot(snapshot.value(), entity.GetBlendMode());
109}
110
111std::optional<Rect> MatrixFilterContents::GetFilterSourceCoverage(
112 const Matrix& effect_transform,
113 const Rect& output_limit) const {
114 auto transform = effect_transform * //
115 matrix_ * //
116 effect_transform.Invert(); //
117 if (transform.GetDeterminant() == 0.0) {
118 return std::nullopt;
119 }
120 auto inverse = transform.Invert();
121 return output_limit.TransformBounds(inverse);
122}
123
126 const Entity& entity,
127 const Matrix& effect_transform) const {
128 if (inputs.empty()) {
129 return std::nullopt;
130 }
131
132 std::optional<Rect> coverage = inputs[0]->GetCoverage(entity);
133 if (!coverage.has_value()) {
134 return std::nullopt;
135 }
136
137 Matrix input_transform = inputs[0]->GetTransform(entity);
138 if (rendering_mode_ ==
140 rendering_mode_ ==
142 Rect coverage_bounds = coverage->TransformBounds(input_transform.Invert());
143 Matrix transform = CalculateSubpassTransform(
144 input_transform, effect_transform, matrix_, rendering_mode_);
145 return coverage_bounds.TransformBounds(transform);
146 } else {
147 Matrix transform = input_transform * //
148 matrix_ * //
149 input_transform.Invert(); //
150 return coverage->TransformBounds(transform);
151 }
152}
153
154} // namespace impeller
static Entity FromSnapshot(const Snapshot &snapshot, BlendMode blend_mode=BlendMode::kSourceOver)
Create an entity that can be used to render a given snapshot.
Definition: entity.cc:22
virtual bool IsTranslationOnly() const
Returns true if this filter graph doesn't perform any basis transforms to the filtered content....
virtual void SetRenderingMode(Entity::RenderingMode rendering_mode)
Marks this filter chain as applying in a subpass scenario.
std::vector< FilterInput::Ref > Vector
Definition: filter_input.h:33
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...
void SetRenderingMode(Entity::RenderingMode rendering_mode) override
Marks this filter chain as applying in a subpass scenario.
bool IsTranslationOnly() const override
Returns true if this filter graph doesn't perform any basis transforms to the filtered content....
void SetSamplerDescriptor(SamplerDescriptor desc)
#define FML_DCHECK(condition)
Definition: logging.h:103
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
TRect< Scalar > Rect
Definition: rect.h:769
SK_API sk_sp< PrecompileColorFilter > Matrix()
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
constexpr bool IsIdentity() const
Definition: matrix.h:379
constexpr Matrix Basis() const
The Matrix without its w components (without translation).
Definition: matrix.h:229
Matrix Invert() const
Definition: matrix.cc:97
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:463