Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
linear_gradient_contents.cc File Reference

Go to the source code of this file.

Namespaces

namespace  impeller
 

Macros

#define ARRAY_LEN(a)   (sizeof(a) / sizeof(a[0]))
 
#define UNIFORM_FRAG_INFO(t)    t##GradientUniformFillPipeline::FragmentShader::FragInfo
 
#define UNIFORM_COLOR_SIZE   ARRAY_LEN(UNIFORM_FRAG_INFO(Linear)::colors)
 
#define UNIFORM_STOP_SIZE   ARRAY_LEN(UNIFORM_FRAG_INFO(Linear)::stop_pairs)
 

Macro Definition Documentation

◆ ARRAY_LEN

#define ARRAY_LEN (   a)    (sizeof(a) / sizeof(a[0]))

Definition at line 195 of file linear_gradient_contents.cc.

◆ UNIFORM_COLOR_SIZE

#define UNIFORM_COLOR_SIZE   ARRAY_LEN(UNIFORM_FRAG_INFO(Linear)::colors)

Definition at line 198 of file linear_gradient_contents.cc.

◆ UNIFORM_FRAG_INFO

#define UNIFORM_FRAG_INFO (   t)     t##GradientUniformFillPipeline::FragmentShader::FragInfo

Definition at line 196 of file linear_gradient_contents.cc.

205 {
206 // TODO(148651): The fast path is overly restrictive, following the design in
207 // https://github.com/flutter/flutter/issues/148651 support for more cases can
208 // be gradually added.
209 if (CanApplyFastGradient()) {
210 return FastLinearGradient(renderer, entity, pass);
211 }
212 if (renderer.GetDeviceCapabilities().SupportsSSBO()) {
213 return RenderSSBO(renderer, entity, pass);
214 }
215 if (colors_.size() <= kMaxUniformGradientStops &&
216 stops_.size() <= kMaxUniformGradientStops) {
217 return RenderUniform(renderer, entity, pass);
218 }
219 return RenderTexture(renderer, entity, pass);
220}
221
222bool LinearGradientContents::RenderTexture(const ContentContext& renderer,
223 const Entity& entity,
224 RenderPass& pass) const {
225 using VS = LinearGradientFillPipeline::VertexShader;
226 using FS = LinearGradientFillPipeline::FragmentShader;
227
228 VS::FrameInfo frame_info;
229 frame_info.matrix = GetInverseEffectTransform();
230
231 PipelineBuilderCallback pipeline_callback =
232 [&renderer](ContentContextOptions options) {
233 return renderer.GetLinearGradientFillPipeline(options);
234 };
235 return ColorSourceContents::DrawGeometry<VS>(
236 renderer, entity, pass, pipeline_callback, frame_info,
237 [this, &renderer, &entity](RenderPass& pass) {
238 auto gradient_data = CreateGradientBuffer(colors_, stops_);
239 auto gradient_texture =
240 CreateGradientTexture(gradient_data, renderer.GetContext());
241 if (gradient_texture == nullptr) {
242 return false;
243 }
244
245 FS::FragInfo frag_info;
246 frag_info.start_point = start_point_;
247 frag_info.end_point = end_point_;
248 frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
249 frag_info.decal_border_color = decal_border_color_;
250 frag_info.texture_sampler_y_coord_scale =
251 gradient_texture->GetYCoordScale();
252 frag_info.alpha =
253 GetOpacityFactor() *
254 GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
255 ;
256 frag_info.half_texel =
257 Vector2(0.5 / gradient_texture->GetSize().width,
258 0.5 / gradient_texture->GetSize().height);
259
260 pass.SetCommandLabel("LinearGradientFill");
261
262 SamplerDescriptor sampler_desc;
263 sampler_desc.min_filter = MinMagFilter::kLinear;
264 sampler_desc.mag_filter = MinMagFilter::kLinear;
265
266 FS::BindTextureSampler(
267 pass, std::move(gradient_texture),
268 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
269 sampler_desc));
270 FS::BindFragInfo(
271 pass, renderer.GetTransientsDataBuffer().EmplaceUniform(frag_info));
272 return true;
273 });
274}
275
276namespace {
277Scalar CalculateInverseDotStartToEnd(Point start_point, Point end_point) {
278 Point start_to_end = end_point - start_point;
279 Scalar dot =
280 (start_to_end.x * start_to_end.x + start_to_end.y * start_to_end.y);
281 return dot == 0.0f ? 0.0f : 1.0f / dot;
282}
283} // namespace
284
285bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
286 const Entity& entity,
287 RenderPass& pass) const {
288 using VS = LinearGradientSSBOFillPipeline::VertexShader;
289 using FS = LinearGradientSSBOFillPipeline::FragmentShader;
290
291 VS::FrameInfo frame_info;
292 frame_info.matrix = GetInverseEffectTransform();
293
294 PipelineBuilderCallback pipeline_callback =
295 [&renderer](ContentContextOptions options) {
296 return renderer.GetLinearGradientSSBOFillPipeline(options);
297 };
298 return ColorSourceContents::DrawGeometry<VS>(
299 renderer, entity, pass, pipeline_callback, frame_info,
300 [this, &renderer, &entity](RenderPass& pass) {
301 FS::FragInfo frag_info;
302 frag_info.start_point = start_point_;
303 frag_info.end_point = end_point_;
304 frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
305 frag_info.decal_border_color = decal_border_color_;
306 frag_info.alpha =
307 GetOpacityFactor() *
308 GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
309 frag_info.start_to_end = end_point_ - start_point_;
310 frag_info.inverse_dot_start_to_end =
311 CalculateInverseDotStartToEnd(start_point_, end_point_);
312
313 auto& data_host_buffer = renderer.GetTransientsDataBuffer();
314 auto colors = CreateGradientColors(colors_, stops_);
315
316 frag_info.colors_length = colors.size();
317 auto color_buffer = data_host_buffer.Emplace(
318 colors.data(), colors.size() * sizeof(StopData),
319 renderer.GetDeviceCapabilities()
320 .GetMinimumStorageBufferAlignment());
321
322 pass.SetCommandLabel("LinearGradientSSBOFill");
323
324 FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
325 FS::BindColorData(pass, color_buffer);
326
327 return true;
328 });
329}
330
331bool LinearGradientContents::RenderUniform(const ContentContext& renderer,
332 const Entity& entity,
333 RenderPass& pass) const {
334 using VS = LinearGradientUniformFillPipeline::VertexShader;
335 using FS = LinearGradientUniformFillPipeline::FragmentShader;
336
337 VS::FrameInfo frame_info;
338 frame_info.matrix = GetInverseEffectTransform();
339
340 PipelineBuilderCallback pipeline_callback =
341 [&renderer](ContentContextOptions options) {
342 return renderer.GetLinearGradientUniformFillPipeline(options);
343 };
344 return ColorSourceContents::DrawGeometry<VS>(
345 renderer, entity, pass, pipeline_callback, frame_info,
346 [this, &renderer, &entity](RenderPass& pass) {
347 FS::FragInfo frag_info;
348 frag_info.start_point = start_point_;
349 frag_info.start_to_end = end_point_ - start_point_;
350 frag_info.alpha =
351 GetOpacityFactor() *
352 GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
353 frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
354 frag_info.colors_length = PopulateUniformGradientColors(
355 colors_, stops_, frag_info.colors, frag_info.stop_pairs);
356 frag_info.inverse_dot_start_to_end =
357 CalculateInverseDotStartToEnd(start_point_, end_point_);
358 frag_info.decal_border_color = decal_border_color_;
359
360 pass.SetCommandLabel("LinearGradientUniformFill");
361
362 FS::BindFragInfo(
363 pass, renderer.GetTransientsDataBuffer().EmplaceUniform(frag_info));
364
365 return true;
366 });
367}
368
369bool LinearGradientContents::ApplyColorFilter(
370 const ColorFilterProc& color_filter_proc) {
371 for (Color& color : colors_) {
372 color = color_filter_proc(color);
373 }
374 decal_border_color_ = color_filter_proc(decal_border_color_);
375 return true;
376}
377
378} // namespace impeller
Point Vector2
Definition point.h:430
float Scalar
Definition scalar.h:19
TPoint< Scalar > Point
Definition point.h:426
LinePipeline::FragmentShader FS
int PopulateUniformGradientColors(const std::vector< Color > &colors, const std::vector< Scalar > &stops, Vector4 frag_info_colors[kMaxUniformGradientStops], Vector4 frag_info_stop_pairs[kMaxUniformGradientStops/2])
Populate 2 arrays with the colors and stop data for a gradient.
std::vector< StopData > CreateGradientColors(const std::vector< Color > &colors, const std::vector< Scalar > &stops)
Populate a vector with the color and stop data for a gradient.
LinePipeline::VertexShader VS
std::shared_ptr< Texture > CreateGradientTexture(const GradientData &gradient_data, const std::shared_ptr< impeller::Context > &context)
Create a host visible texture that contains the gradient defined by the provided gradient data.
GradientData CreateGradientBuffer(const std::vector< Color > &colors, const std::vector< Scalar > &stops)
Populate a vector with the interpolated color bytes for the linear gradient described by colors and s...
Definition gradient.cc:20

◆ UNIFORM_STOP_SIZE

#define UNIFORM_STOP_SIZE   ARRAY_LEN(UNIFORM_FRAG_INFO(Linear)::stop_pairs)

Definition at line 199 of file linear_gradient_contents.cc.