35 morph_type_ = morph_type;
38 std::optional<Entity> DirectionalMorphologyFilterContents::RenderFilter(
42 const Matrix& effect_transform,
44 const std::optional<Rect>& coverage_hint)
const {
56 auto input_snapshot = inputs[0]->GetSnapshot(
"Morphology", renderer, entity);
57 if (!input_snapshot.has_value()) {
65 auto maybe_input_uvs = input_snapshot->GetCoverageUVs(coverage);
66 if (!maybe_input_uvs.has_value()) {
69 auto input_uvs = maybe_input_uvs.value();
77 auto& host_buffer = renderer.GetTransientsBuffer();
79 std::array<VS::PerVertexData, 4> vertices = {
80 VS::PerVertexData{
Point(0, 0), input_uvs[0]},
81 VS::PerVertexData{
Point(1, 0), input_uvs[1]},
82 VS::PerVertexData{
Point(0, 1), input_uvs[2]},
83 VS::PerVertexData{
Point(1, 1), input_uvs[3]},
86 VS::FrameInfo frame_info;
88 frame_info.texture_sampler_y_coord_scale =
89 input_snapshot->texture->GetYCoordScale();
92 auto transformed_radius =
94 auto transformed_texture_vertices =
97 auto transformed_texture_width =
98 transformed_texture_vertices[0].GetDistance(
99 transformed_texture_vertices[1]);
100 auto transformed_texture_height =
101 transformed_texture_vertices[0].GetDistance(
102 transformed_texture_vertices[2]);
104 FS::FragInfo frag_info;
105 frag_info.radius = std::round(transformed_radius.GetLength());
106 frag_info.morph_type =
static_cast<Scalar>(morph_type_);
107 frag_info.uv_offset =
108 input_snapshot->transform.Invert()
109 .TransformDirection(transformed_radius)
111 Point(transformed_texture_width, transformed_texture_height);
113 pass.SetCommandLabel(
"Morphology Filter");
117 pass.SetPipeline(renderer.GetMorphologyFilterPipeline(options));
120 auto sampler_descriptor = input_snapshot->sampler_descriptor;
121 if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {
126 FS::BindTextureSampler(
127 pass, input_snapshot->texture,
128 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
129 sampler_descriptor));
130 VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
131 FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
133 return pass.Draw().ok();
135 std::shared_ptr<CommandBuffer> command_buffer =
136 renderer.GetContext()->CreateCommandBuffer();
137 if (command_buffer ==
nullptr) {
141 fml::StatusOr<RenderTarget> render_target =
142 renderer.MakeSubpass(
"Directional Morphology Filter",
144 if (!render_target.ok()) {
147 if (!renderer.GetContext()
149 ->Submit({std::move(command_buffer)})
154 SamplerDescriptor sampler_desc;
159 Snapshot{.texture = render_target.value().GetRenderTargetTexture(),
161 .sampler_descriptor = sampler_desc,
162 .opacity = input_snapshot->opacity},
169 const Matrix& effect_transform)
const {
170 if (inputs.empty()) {
174 auto coverage = inputs[0]->GetCoverage(entity);
175 if (!coverage.has_value()) {
178 auto transform = inputs[0]->GetTransform(entity) * effect_transform.
Basis();
179 auto transformed_vector =
184 switch (morph_type_) {
186 origin -= transformed_vector;
187 size += transformed_vector * 2;
190 origin += transformed_vector;
191 size -= transformed_vector * 2;
194 if (size.x < 0 || size.y < 0) {
202 const Matrix& effect_transform,
203 const Rect& output_limit)
const {
204 auto transformed_vector =
206 switch (morph_type_) {
208 return output_limit.
Expand(-transformed_vector);
210 return output_limit.
Expand(transformed_vector);