Skip to content

[Impeller] Improve performance of blended drawAtlas calls. #120925

@jonahwilliams

Description

@jonahwilliams

When supplied with colors and a blend mode, the current implementation of drawAtlas performs the blending by drawing both the colors and textures into a subpass and then combines them with a blending ColorFilter. On the wonderous app, this performs quite poorly for a number of reasons:

  • The subpass size ends up being the coverage size of the final atlas draw call. In the wonderous example, this is nearly the size of the entire screen as the confetti effect goes every. Creating huge subpasses and then texture filling them is quite expensive even on high end devices.
  • blend ColorFilters aren't efficient when using advanced blends on iOS. We need to switch to the FramebufferBlend.
  • The blending may not be correct if the colors have opacity and end up stacked. Skia behaves as if the texture and color were blended in the shder.
  • We compute the blend of color and sample rect potentially multiple times for the same combinations. For example, in wonderous despite drawing a few hundred confettis only a dozen or so are unique.

To solve this problem I'd propose that we implement blending (excluding clear, src, and dst modes) by generating a subatlass on the fly. This would by keyed based on int color + sample rect to compress the number entries, and should be much smaller reducing the cost of the subpass.

The final draw call would then sample from this atlas instead of the original atlas.

Motivating Screenshots:

image

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work liste: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions