@@ -25,23 +25,43 @@ static bool AdvancedBlend(const FilterInput::Vector& inputs,
25
25
const ContentContext& renderer,
26
26
const Entity& entity,
27
27
RenderPass& pass,
28
- const Rect & bounds ,
28
+ const Rect & coverage ,
29
29
PipelineProc pipeline_proc) {
30
30
if (inputs.size () < 2 ) {
31
31
return false ;
32
32
}
33
33
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
+
34
54
auto & host_buffer = pass.GetTransientsBuffer ();
35
55
36
56
auto size = pass.GetRenderTargetSize ();
37
57
VertexBufferBuilder<typename VS::PerVertexData> vtx_builder;
38
58
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 ] },
45
65
});
46
66
auto vtx_buffer = vtx_builder.CreateVertexBuffer (host_buffer);
47
67
@@ -56,25 +76,12 @@ static bool AdvancedBlend(const FilterInput::Vector& inputs,
56
76
cmd.pipeline = std::move (pipeline);
57
77
58
78
auto sampler = renderer.GetContext ()->GetSamplerLibrary ()->GetSampler ({});
79
+ FS::BindTextureSamplerDst (cmd, dst_snapshot->texture , sampler);
80
+ FS::BindTextureSamplerSrc (cmd, src_snapshot->texture , sampler);
81
+
59
82
typename VS::FrameInfo frame_info;
60
83
frame_info.mvp = Matrix::MakeOrthographic (size);
61
84
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
-
78
85
auto uniform_view = host_buffer.EmplaceUniform (frame_info);
79
86
VS::BindFrameInfo (cmd, uniform_view);
80
87
pass.AddCommand (cmd);
@@ -99,11 +106,11 @@ void BlendFilterContents::SetBlendMode(Entity::BlendMode blend_mode) {
99
106
advanced_blend_proc_ = [](const FilterInput::Vector& inputs,
100
107
const ContentContext& renderer,
101
108
const Entity& entity, RenderPass& pass,
102
- const Rect & bounds ) {
109
+ const Rect & coverage ) {
103
110
PipelineProc p = &ContentContext::GetTextureBlendScreenPipeline;
104
111
return AdvancedBlend<TextureBlendScreenPipeline::VertexShader,
105
112
TextureBlendScreenPipeline::FragmentShader>(
106
- inputs, renderer, entity, pass, bounds , p);
113
+ inputs, renderer, entity, pass, coverage , p);
107
114
};
108
115
break ;
109
116
default :
@@ -116,49 +123,62 @@ static bool BasicBlend(const FilterInput::Vector& inputs,
116
123
const ContentContext& renderer,
117
124
const Entity& entity,
118
125
RenderPass& pass,
119
- const Rect & bounds ,
126
+ const Rect & coverage ,
120
127
Entity::BlendMode basic_blend) {
121
128
using VS = TextureBlendPipeline::VertexShader;
122
129
using FS = TextureBlendPipeline::FragmentShader;
123
130
124
131
auto & host_buffer = pass.GetTransientsBuffer ();
125
132
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
-
138
133
auto sampler = renderer.GetContext ()->GetSamplerLibrary ()->GetSampler ({});
139
134
140
- // Draw the first texture using kSource.
141
-
142
135
Command cmd;
143
136
cmd.label = " Basic Blend Filter" ;
144
- cmd.BindVertices (vtx_buffer);
145
137
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
+
150
148
FS::BindTextureSamplerSrc (cmd, input->texture , sampler);
151
149
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
+
152
163
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 ;
157
167
158
168
auto uniform_view = host_buffer.EmplaceUniform (frame_info);
159
169
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 ;
160
181
}
161
- pass.AddCommand (cmd);
162
182
163
183
if (inputs.size () < 2 ) {
164
184
return true ;
@@ -172,17 +192,9 @@ static bool BasicBlend(const FilterInput::Vector& inputs,
172
192
for (auto texture_i = inputs.begin () + 1 ; texture_i < inputs.end ();
173
193
texture_i++) {
174
194
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
+ }
186
198
}
187
199
188
200
return true ;
@@ -192,23 +204,23 @@ bool BlendFilterContents::RenderFilter(const FilterInput::Vector& inputs,
192
204
const ContentContext& renderer,
193
205
const Entity& entity,
194
206
RenderPass& pass,
195
- const Rect & bounds ) const {
207
+ const Rect & coverage ) const {
196
208
if (inputs.empty ()) {
197
209
return true ;
198
210
}
199
211
200
212
if (inputs.size () == 1 ) {
201
213
// Nothing to blend.
202
- return BasicBlend (inputs, renderer, entity, pass, bounds ,
214
+ return BasicBlend (inputs, renderer, entity, pass, coverage ,
203
215
Entity::BlendMode::kSource );
204
216
}
205
217
206
218
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_);
208
220
}
209
221
210
222
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 );
212
224
}
213
225
214
226
FML_UNREACHABLE ();
0 commit comments