Flutter Engine
 
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 190 of file linear_gradient_contents.cc.

◆ UNIFORM_COLOR_SIZE

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

Definition at line 193 of file linear_gradient_contents.cc.

◆ UNIFORM_FRAG_INFO

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

Definition at line 191 of file linear_gradient_contents.cc.

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