@@ -25,23 +25,43 @@ static bool AdvancedBlend(const FilterInput::Vector& inputs,
2525 const ContentContext& renderer,
2626 const Entity& entity,
2727 RenderPass& pass,
28- const Rect& bounds ,
28+ const Rect& coverage ,
2929 PipelineProc pipeline_proc) {
3030 if (inputs.size () < 2 ) {
3131 return false ;
3232 }
3333
34+ auto dst_snapshot = inputs[1 ]->GetSnapshot (renderer, entity);
35+ if (!dst_snapshot.has_value ()) {
36+ return true ;
37+ }
38+ auto maybe_dst_uvs = dst_snapshot->GetCoverageUVs (coverage);
39+ if (!maybe_dst_uvs.has_value ()) {
40+ return true ;
41+ }
42+ auto dst_uvs = maybe_dst_uvs.value ();
43+
44+ auto src_snapshot = inputs[0 ]->GetSnapshot (renderer, entity);
45+ if (!src_snapshot.has_value ()) {
46+ return true ;
47+ }
48+ auto maybe_src_uvs = src_snapshot->GetCoverageUVs (coverage);
49+ if (!maybe_src_uvs.has_value ()) {
50+ return true ;
51+ }
52+ auto src_uvs = maybe_src_uvs.value ();
53+
3454 auto & host_buffer = pass.GetTransientsBuffer ();
3555
3656 auto size = pass.GetRenderTargetSize ();
3757 VertexBufferBuilder<typename VS::PerVertexData> vtx_builder;
3858 vtx_builder.AddVertices ({
39- {Point (0 , 0 ), Point ( 0 , 0 ) },
40- {Point (size.width , 0 ), Point ( 1 , 0 ) },
41- {Point (size.width , size.height ), Point ( 1 , 1 ) },
42- {Point (0 , 0 ), Point ( 0 , 0 ) },
43- {Point (size.width , size.height ), Point ( 1 , 1 ) },
44- {Point (0 , size.height ), Point ( 0 , 1 ) },
59+ {Point (0 , 0 ), dst_uvs[ 0 ], src_uvs[ 0 ] },
60+ {Point (size.width , 0 ), dst_uvs[ 1 ], src_uvs[ 1 ] },
61+ {Point (size.width , size.height ), dst_uvs[ 3 ], src_uvs[ 3 ] },
62+ {Point (0 , 0 ), dst_uvs[ 0 ], src_uvs[ 0 ] },
63+ {Point (size.width , size.height ), dst_uvs[ 3 ], src_uvs[ 3 ] },
64+ {Point (0 , size.height ), dst_uvs[ 2 ], src_uvs[ 2 ] },
4565 });
4666 auto vtx_buffer = vtx_builder.CreateVertexBuffer (host_buffer);
4767
@@ -56,25 +76,12 @@ static bool AdvancedBlend(const FilterInput::Vector& inputs,
5676 cmd.pipeline = std::move (pipeline);
5777
5878 auto sampler = renderer.GetContext ()->GetSamplerLibrary ()->GetSampler ({});
79+ FS::BindTextureSamplerDst (cmd, dst_snapshot->texture , sampler);
80+ FS::BindTextureSamplerSrc (cmd, src_snapshot->texture , sampler);
81+
5982 typename VS::FrameInfo frame_info;
6083 frame_info.mvp = Matrix::MakeOrthographic (size);
6184
62- auto dst_snapshot = inputs[1 ]->GetSnapshot (renderer, entity);
63- FS::BindTextureSamplerSrc (cmd, dst_snapshot->texture , sampler);
64- frame_info.dst_uv_transform =
65- Matrix::MakeTranslation (-(dst_snapshot->position - bounds.origin ) /
66- size) *
67- Matrix::MakeScale (
68- Vector3 (Size (size) / Size (dst_snapshot->texture ->GetSize ())));
69-
70- auto src_snapshot = inputs[0 ]->GetSnapshot (renderer, entity);
71- FS::BindTextureSamplerDst (cmd, src_snapshot->texture , sampler);
72- frame_info.src_uv_transform =
73- Matrix::MakeTranslation (-(src_snapshot->position - bounds.origin ) /
74- size) *
75- Matrix::MakeScale (
76- Vector3 (Size (size) / Size (src_snapshot->texture ->GetSize ())));
77-
7885 auto uniform_view = host_buffer.EmplaceUniform (frame_info);
7986 VS::BindFrameInfo (cmd, uniform_view);
8087 pass.AddCommand (cmd);
@@ -99,11 +106,11 @@ void BlendFilterContents::SetBlendMode(Entity::BlendMode blend_mode) {
99106 advanced_blend_proc_ = [](const FilterInput::Vector& inputs,
100107 const ContentContext& renderer,
101108 const Entity& entity, RenderPass& pass,
102- const Rect& bounds ) {
109+ const Rect& coverage ) {
103110 PipelineProc p = &ContentContext::GetTextureBlendScreenPipeline;
104111 return AdvancedBlend<TextureBlendScreenPipeline::VertexShader,
105112 TextureBlendScreenPipeline::FragmentShader>(
106- inputs, renderer, entity, pass, bounds , p);
113+ inputs, renderer, entity, pass, coverage , p);
107114 };
108115 break ;
109116 default :
@@ -116,49 +123,62 @@ static bool BasicBlend(const FilterInput::Vector& inputs,
116123 const ContentContext& renderer,
117124 const Entity& entity,
118125 RenderPass& pass,
119- const Rect& bounds ,
126+ const Rect& coverage ,
120127 Entity::BlendMode basic_blend) {
121128 using VS = TextureBlendPipeline::VertexShader;
122129 using FS = TextureBlendPipeline::FragmentShader;
123130
124131 auto & host_buffer = pass.GetTransientsBuffer ();
125132
126- auto size = pass.GetRenderTargetSize ();
127- VertexBufferBuilder<VS::PerVertexData> vtx_builder;
128- vtx_builder.AddVertices ({
129- {Point (0 , 0 ), Point (0 , 0 )},
130- {Point (size.width , 0 ), Point (1 , 0 )},
131- {Point (size.width , size.height ), Point (1 , 1 )},
132- {Point (0 , 0 ), Point (0 , 0 )},
133- {Point (size.width , size.height ), Point (1 , 1 )},
134- {Point (0 , size.height ), Point (0 , 1 )},
135- });
136- auto vtx_buffer = vtx_builder.CreateVertexBuffer (host_buffer);
137-
138133 auto sampler = renderer.GetContext ()->GetSamplerLibrary ()->GetSampler ({});
139134
140- // Draw the first texture using kSource.
141-
142135 Command cmd;
143136 cmd.label = " Basic Blend Filter" ;
144- cmd.BindVertices (vtx_buffer);
145137 auto options = OptionsFromPass (pass);
146- options.blend_mode = Entity::BlendMode::kSource ;
147- cmd.pipeline = renderer.GetTextureBlendPipeline (options);
148- {
149- auto input = inputs[0 ]->GetSnapshot (renderer, entity);
138+
139+ auto add_blend_command = [&](std::optional<Snapshot> input) {
140+ if (!input.has_value ()) {
141+ return false ;
142+ }
143+ auto input_coverage = input->GetCoverage ();
144+ if (!input_coverage.has_value ()) {
145+ return false ;
146+ }
147+
150148 FS::BindTextureSamplerSrc (cmd, input->texture , sampler);
151149
150+ auto size = input->texture ->GetSize ();
151+ VertexBufferBuilder<VS::PerVertexData> vtx_builder;
152+ vtx_builder.AddVertices ({
153+ {Point (0 , 0 ), Point (0 , 0 )},
154+ {Point (size.width , 0 ), Point (1 , 0 )},
155+ {Point (size.width , size.height ), Point (1 , 1 )},
156+ {Point (0 , 0 ), Point (0 , 0 )},
157+ {Point (size.width , size.height ), Point (1 , 1 )},
158+ {Point (0 , size.height ), Point (0 , 1 )},
159+ });
160+ auto vtx_buffer = vtx_builder.CreateVertexBuffer (host_buffer);
161+ cmd.BindVertices (vtx_buffer);
162+
152163 VS::FrameInfo frame_info;
153- frame_info.mvp =
154- Matrix::MakeOrthographic (size) *
155- Matrix::MakeTranslation (input->position - bounds.origin ) *
156- Matrix::MakeScale (Size (input->texture ->GetSize ()) / Size (size));
164+ frame_info.mvp = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
165+ Matrix::MakeTranslation (-coverage.origin ) *
166+ input->transform ;
157167
158168 auto uniform_view = host_buffer.EmplaceUniform (frame_info);
159169 VS::BindFrameInfo (cmd, uniform_view);
170+
171+ pass.AddCommand (cmd);
172+ return true ;
173+ };
174+
175+ // Draw the first texture using kSource.
176+
177+ options.blend_mode = Entity::BlendMode::kSource ;
178+ cmd.pipeline = renderer.GetTextureBlendPipeline (options);
179+ if (!add_blend_command (inputs[0 ]->GetSnapshot (renderer, entity))) {
180+ return true ;
160181 }
161- pass.AddCommand (cmd);
162182
163183 if (inputs.size () < 2 ) {
164184 return true ;
@@ -172,17 +192,9 @@ static bool BasicBlend(const FilterInput::Vector& inputs,
172192 for (auto texture_i = inputs.begin () + 1 ; texture_i < inputs.end ();
173193 texture_i++) {
174194 auto input = texture_i->get ()->GetSnapshot (renderer, entity);
175- FS::BindTextureSamplerSrc (cmd, input->texture , sampler);
176-
177- VS::FrameInfo frame_info;
178- frame_info.mvp = frame_info.mvp =
179- Matrix::MakeOrthographic (size) *
180- Matrix::MakeTranslation (input->position - bounds.origin ) *
181- Matrix::MakeScale (Size (input->texture ->GetSize ()) / Size (size));
182-
183- auto uniform_view = host_buffer.EmplaceUniform (frame_info);
184- VS::BindFrameInfo (cmd, uniform_view);
185- pass.AddCommand (cmd);
195+ if (!add_blend_command (input)) {
196+ return true ;
197+ }
186198 }
187199
188200 return true ;
@@ -192,23 +204,23 @@ bool BlendFilterContents::RenderFilter(const FilterInput::Vector& inputs,
192204 const ContentContext& renderer,
193205 const Entity& entity,
194206 RenderPass& pass,
195- const Rect& bounds ) const {
207+ const Rect& coverage ) const {
196208 if (inputs.empty ()) {
197209 return true ;
198210 }
199211
200212 if (inputs.size () == 1 ) {
201213 // Nothing to blend.
202- return BasicBlend (inputs, renderer, entity, pass, bounds ,
214+ return BasicBlend (inputs, renderer, entity, pass, coverage ,
203215 Entity::BlendMode::kSource );
204216 }
205217
206218 if (blend_mode_ <= Entity::BlendMode::kLastPipelineBlendMode ) {
207- return BasicBlend (inputs, renderer, entity, pass, bounds , blend_mode_);
219+ return BasicBlend (inputs, renderer, entity, pass, coverage , blend_mode_);
208220 }
209221
210222 if (blend_mode_ <= Entity::BlendMode::kLastAdvancedBlendMode ) {
211- return advanced_blend_proc_ (inputs, renderer, entity, pass, bounds );
223+ return advanced_blend_proc_ (inputs, renderer, entity, pass, coverage );
212224 }
213225
214226 FML_UNREACHABLE ();
0 commit comments