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.alpha =
251 GetOpacityFactor() *
252 GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
253 ;
254 frag_info.half_texel =
255 Vector2(0.5 / gradient_texture->GetSize().width,
256 0.5 / gradient_texture->GetSize().height);
257
258 pass.SetCommandLabel("LinearGradientFill");
259
260 SamplerDescriptor sampler_desc;
261 sampler_desc.min_filter = MinMagFilter::kLinear;
262 sampler_desc.mag_filter = MinMagFilter::kLinear;
263
264 FS::BindTextureSampler(
265 pass, std::move(gradient_texture),
266 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
267 sampler_desc));
268 FS::BindFragInfo(
269 pass, renderer.GetTransientsDataBuffer().EmplaceUniform(frag_info));
270 return true;
271 });
272}
273
274namespace {
275Scalar CalculateInverseDotStartToEnd(Point start_point, Point end_point) {
276 Point start_to_end = end_point - start_point;
277 Scalar dot =
278 (start_to_end.x * start_to_end.x + start_to_end.y * start_to_end.y);
279 return dot == 0.0f ? 0.0f : 1.0f / dot;
280}
281} // namespace
282
283bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
284 const Entity& entity,
285 RenderPass& pass) const {
286 using VS = LinearGradientSSBOFillPipeline::VertexShader;
287 using FS = LinearGradientSSBOFillPipeline::FragmentShader;
288
289 VS::FrameInfo frame_info;
290 frame_info.matrix = GetInverseEffectTransform();
291
292 PipelineBuilderCallback pipeline_callback =
293 [&renderer](ContentContextOptions options) {
294 return renderer.GetLinearGradientSSBOFillPipeline(options);
295 };
296 return ColorSourceContents::DrawGeometry<VS>(
297 renderer, entity, pass, pipeline_callback, frame_info,
298 [this, &renderer, &entity](RenderPass& pass) {
299 FS::FragInfo frag_info;
300 frag_info.start_point = start_point_;
301 frag_info.end_point = end_point_;
302 frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
303 frag_info.decal_border_color = decal_border_color_;
304 frag_info.alpha =
305 GetOpacityFactor() *
306 GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
307 frag_info.start_to_end = end_point_ - start_point_;
308 frag_info.inverse_dot_start_to_end =
309 CalculateInverseDotStartToEnd(start_point_, end_point_);
310
311 auto& data_host_buffer = renderer.GetTransientsDataBuffer();
312 auto colors = CreateGradientColors(colors_, stops_);
313
314 frag_info.colors_length = colors.size();
315 auto color_buffer = data_host_buffer.Emplace(
316 colors.data(), colors.size() * sizeof(StopData),
317 renderer.GetDeviceCapabilities()
318 .GetMinimumStorageBufferAlignment());
319
320 pass.SetCommandLabel("LinearGradientSSBOFill");
321
322 FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
323 FS::BindColorData(pass, color_buffer);
324
325 return true;
326 });
327}
328
329bool LinearGradientContents::RenderUniform(const ContentContext& renderer,
330 const Entity& entity,
331 RenderPass& pass) const {
332 using VS = LinearGradientUniformFillPipeline::VertexShader;
333 using FS = LinearGradientUniformFillPipeline::FragmentShader;
334
335 VS::FrameInfo frame_info;
336 frame_info.matrix = GetInverseEffectTransform();
337
338 PipelineBuilderCallback pipeline_callback =
339 [&renderer](ContentContextOptions options) {
340 return renderer.GetLinearGradientUniformFillPipeline(options);
341 };
342 return ColorSourceContents::DrawGeometry<VS>(
343 renderer, entity, pass, pipeline_callback, frame_info,
344 [this, &renderer, &entity](RenderPass& pass) {
345 FS::FragInfo frag_info;
346 frag_info.start_point = start_point_;
347 frag_info.start_to_end = end_point_ - start_point_;
348 frag_info.alpha =
349 GetOpacityFactor() *
350 GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
351 frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
352 frag_info.colors_length = PopulateUniformGradientColors(
353 colors_, stops_, frag_info.colors, frag_info.stop_pairs);
354 frag_info.inverse_dot_start_to_end =
355 CalculateInverseDotStartToEnd(start_point_, end_point_);
356 frag_info.decal_border_color = decal_border_color_;
357
358 pass.SetCommandLabel("LinearGradientUniformFill");
359
360 FS::BindFragInfo(
361 pass, renderer.GetTransientsDataBuffer().EmplaceUniform(frag_info));
362
363 return true;
364 });
365}
366
367bool LinearGradientContents::ApplyColorFilter(
368 const ColorFilterProc& color_filter_proc) {
369 for (Color& color : colors_) {
370 color = color_filter_proc(color);
371 }
372 decal_border_color_ = color_filter_proc(decal_border_color_);
373 return true;
374}
375
376} // 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.