Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
morphology_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#include <cmath>
8
14
15namespace impeller {
16
18 default;
19
21 default;
22
24 radius_ = radius;
25}
26
28 direction_ = direction.Normalize();
29 if (direction_.IsZero()) {
30 direction_ = Vector2(0, 1);
31 }
32}
33
35 morph_type_ = morph_type;
36}
37
39 const FilterInput::Vector& inputs,
40 const ContentContext& renderer,
41 const Entity& entity,
42 const Matrix& effect_transform,
43 const Rect& coverage,
44 const std::optional<Rect>& coverage_hint) const {
47
48 //----------------------------------------------------------------------------
49 /// Handle inputs.
50 ///
51
52 if (inputs.empty()) {
53 return std::nullopt;
54 }
55
56 auto input_snapshot = inputs[0]->GetSnapshot("Morphology", renderer, entity);
57 if (!input_snapshot.has_value()) {
58 return std::nullopt;
59 }
60
61 if (radius_.radius < kEhCloseEnough) {
62 return Entity::FromSnapshot(input_snapshot.value(), entity.GetBlendMode());
63 }
64
65 auto maybe_input_uvs = input_snapshot->GetCoverageUVs(coverage);
66 if (!maybe_input_uvs.has_value()) {
67 return std::nullopt;
68 }
69 auto input_uvs = maybe_input_uvs.value();
70
71 //----------------------------------------------------------------------------
72 /// Render to texture.
73 ///
74
76 RenderPass& pass) {
77 auto& host_buffer = renderer.GetTransientsBuffer();
78
80 vtx_builder.AddVertices({
81 {Point(0, 0), input_uvs[0]},
82 {Point(1, 0), input_uvs[1]},
83 {Point(0, 1), input_uvs[2]},
84 {Point(1, 1), input_uvs[3]},
85 });
86
87 VS::FrameInfo frame_info;
88 frame_info.mvp = Matrix::MakeOrthographic(ISize(1, 1));
89 frame_info.texture_sampler_y_coord_scale =
90 input_snapshot->texture->GetYCoordScale();
91
92 auto transform = entity.GetTransform() * effect_transform.Basis();
93 auto transformed_radius =
94 transform.TransformDirection(direction_ * radius_.radius);
95 auto transformed_texture_vertices =
96 Rect::MakeSize(input_snapshot->texture->GetSize())
97 .GetTransformedPoints(input_snapshot->transform);
98 auto transformed_texture_width =
99 transformed_texture_vertices[0].GetDistance(
100 transformed_texture_vertices[1]);
101 auto transformed_texture_height =
102 transformed_texture_vertices[0].GetDistance(
103 transformed_texture_vertices[2]);
104
105 FS::FragInfo frag_info;
106 frag_info.radius = std::round(transformed_radius.GetLength());
107 frag_info.morph_type = static_cast<Scalar>(morph_type_);
108 frag_info.uv_offset =
109 input_snapshot->transform.Invert()
110 .TransformDirection(transformed_radius)
111 .Normalize() /
112 Point(transformed_texture_width, transformed_texture_height);
113
114 pass.SetCommandLabel("Morphology Filter");
115 auto options = OptionsFromPass(pass);
116 options.primitive_type = PrimitiveType::kTriangleStrip;
117 options.blend_mode = BlendMode::kSource;
118 pass.SetPipeline(renderer.GetMorphologyFilterPipeline(options));
119 pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
120
121 auto sampler_descriptor = input_snapshot->sampler_descriptor;
122 if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {
123 sampler_descriptor.width_address_mode = SamplerAddressMode::kDecal;
124 sampler_descriptor.height_address_mode = SamplerAddressMode::kDecal;
125 }
126
127 FS::BindTextureSampler(
128 pass, input_snapshot->texture,
129 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
130 sampler_descriptor));
131 VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
132 FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
133
134 return pass.Draw().ok();
135 };
136 std::shared_ptr<CommandBuffer> command_buffer =
137 renderer.GetContext()->CreateCommandBuffer();
138 if (command_buffer == nullptr) {
139 return std::nullopt;
140 }
141
142 fml::StatusOr<RenderTarget> render_target =
143 renderer.MakeSubpass("Directional Morphology Filter",
144 ISize(coverage.GetSize()), command_buffer, callback);
145 if (!render_target.ok()) {
146 return std::nullopt;
147 }
148 if (!renderer.GetContext()
149 ->GetCommandQueue()
150 ->Submit(/*buffers=*/{std::move(command_buffer)})
151 .ok()) {
152 return std::nullopt;
153 }
154
155 SamplerDescriptor sampler_desc;
156 sampler_desc.min_filter = MinMagFilter::kLinear;
157 sampler_desc.mag_filter = MinMagFilter::kLinear;
158
160 Snapshot{.texture = render_target.value().GetRenderTargetTexture(),
161 .transform = Matrix::MakeTranslation(coverage.GetOrigin()),
162 .sampler_descriptor = sampler_desc,
163 .opacity = input_snapshot->opacity},
164 entity.GetBlendMode());
165}
166
168 const FilterInput::Vector& inputs,
169 const Entity& entity,
170 const Matrix& effect_transform) const {
171 if (inputs.empty()) {
172 return std::nullopt;
173 }
174
175 auto coverage = inputs[0]->GetCoverage(entity);
176 if (!coverage.has_value()) {
177 return std::nullopt;
178 }
179 auto transform = inputs[0]->GetTransform(entity) * effect_transform.Basis();
180 auto transformed_vector =
181 transform.TransformDirection(direction_ * radius_.radius).Abs();
182
183 auto origin = coverage->GetOrigin();
184 auto size = Vector2(coverage->GetSize());
185 switch (morph_type_) {
187 origin -= transformed_vector;
188 size += transformed_vector * 2;
189 break;
191 origin += transformed_vector;
192 size -= transformed_vector * 2;
193 break;
194 }
195 if (size.x < 0 || size.y < 0) {
196 return Rect::MakeSize(Size(0, 0));
197 }
198 return Rect::MakeOriginSize(origin, Size(size.x, size.y));
199}
200
201std::optional<Rect>
203 const Matrix& effect_transform,
204 const Rect& output_limit) const {
205 auto transformed_vector =
206 effect_transform.TransformDirection(direction_ * radius_.radius).Abs();
207 switch (morph_type_) {
209 return output_limit.Expand(-transformed_vector);
211 return output_limit.Expand(transformed_vector);
212 }
213}
214
215} // namespace impeller
const char * options
const T & value() const
Definition status_or.h:77
bool ok() const
Definition status_or.h:75
std::function< bool(const ContentContext &, RenderPass &)> SubpassCallback
std::optional< Entity > RenderFilter(const FilterInput::Vector &input_textures, const ContentContext &renderer, const Entity &entity, const Matrix &effect_transform, const Rect &coverage, const std::optional< Rect > &coverage_hint) const override
Converts zero or more filter inputs into a render instruction.
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...
std::optional< Rect > GetFilterSourceCoverage(const Matrix &effect_transform, const Rect &output_limit) const override
Internal utility method for |GetSourceCoverage| that computes the inverse effect of this transform on...
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
BlendMode GetBlendMode() const
Definition entity.cc:119
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition entity.cc:46
std::vector< FilterInput::Ref > Vector
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition render_pass.h:33
FragmentShader_ FragmentShader
Definition pipeline.h:106
VertexBuffer CreateVertexBuffer(HostBuffer &host_buffer) const
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Point Vector2
Definition point.h:320
float Scalar
Definition scalar.h:18
constexpr float kEhCloseEnough
Definition constants.h:56
SolidFillVertexShader VS
TPoint< Scalar > Point
Definition point.h:316
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...
TSize< int64_t > ISize
Definition size.h:138
TSize< Scalar > Size
Definition size.h:137
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition contents.cc:20
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition p3.cpp:47
A 4x4 matrix using column-major storage.
Definition matrix.h:37
static constexpr Matrix MakeOrthographic(TSize< T > size)
Definition matrix.h:495
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition matrix.h:95
constexpr Matrix Basis() const
The Matrix without its w components (without translation).
Definition matrix.h:229
constexpr Vector4 TransformDirection(const Vector4 &v) const
Definition matrix.h:469
For convolution filters, the "radius" is the size of the convolution kernel to use on the local space...
Definition sigma.h:48
Scalar radius
Definition sigma.h:49
Represents a texture and its intended draw transform/sampler configuration.
Definition snapshot.h:24
std::shared_ptr< Texture > texture
Definition snapshot.h:25
constexpr TPoint Normalize() const
Definition point.h:208
constexpr bool IsZero() const
Definition point.h:234
static constexpr TRect MakeOriginSize(const TPoint< Type > &origin, const TSize< Type > &size)
Definition rect.h:140
constexpr std::array< TPoint< T >, 4 > GetTransformedPoints(const Matrix &transform) const
Definition rect.h:394
static constexpr TRect MakeSize(const TSize< U > &size)
Definition rect.h:146
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
Definition rect.h:582