Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@jonahwilliams
Copy link
Contributor

Fixes flutter/flutter#119474

I'm not actually sure if this is correct! But this improves wonderous frame times on the wonders screen by ~20 FPS on the iPad pro.

@jonahwilliams
Copy link
Contributor Author

Need to double check but I think specifically for images we document the opacity as applying at the end so it may be OK

@jonahwilliams
Copy link
Contributor Author

This is visually correct because we apply absorbed opacity before the filters. Not sure if the check for the mask is appropriate though

jonahwilliams added 2 commits January 30, 2023 09:13
@jonahwilliams jonahwilliams marked this pull request as ready for review January 30, 2023 17:22
jonahwilliams added 2 commits January 30, 2023 09:23
@chinmaygarde chinmaygarde changed the title [impeller] let images with opacity and filters passthrough [Impeller] let images with opacity and filters passthrough. Jan 31, 2023
}

bool Paint::HasFilters() const {
return color_filter.has_value();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why color filters specifically? Not all color filters absorb opacity IIRC.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I should check for this with #39266

The general answer is that the high level framework API makes it extrenely easy to apply color blend filters to images, and no other type of color or image filter. see color and colorBlendMode in https://api.flutter.dev/flutter/widgets/Image-class.html

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of now, all color filters absorb opacity.

/// @brief Whether this paint has a filter that can apply opacity
///
/// Only color filters can absorb opacity currently.
bool HasFilters() const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just checks for a color filter, not any filter. So perhaps name HasColorFilter instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

contents->SetSourceRect(source);
contents->SetSamplerDescriptor(std::move(sampler));
contents->SetOpacity(paint.color.alpha);
contents->SetDeferApplyingOpacity(paint.HasFilters());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feature was added in order to apply the opacity in the correct order in some cases. Unfortunately, opacity is starting to get kind of hard to reason about in Impeller.

Would this still work correctly when:

  1. An image filter is present along with a color filter?
  2. An advanced blend + a color filter is being used?

cc @ColdPaleLight , who had to contend with opacity deferral here: #36279

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1/2 essentially don't matter for performance (though they certainly do for correctness). The issue we need to contend with is that Flutter makes it very easy to add a color+blend to an image, and its expected that this is only marginally more expensive than drawing the image itself (probably due to skia genering shaders for this).

So one partial solution is what I have here, but perhaps this is pushing the implementation in the wrong direction. In all of the cases I'm worried about, we'll get some drawing primitive (drawRect + tiled texture), drawImageRect, drawImageNine, and then a paint with a color filter on it.

Perhaps the way to go about this is to recognize specifically that case (requiring that color sources and color filters are typed and not just opaque procs), and then create a specialized contents for it. That would also make it easier to fix a simialr problem with tiled textures where we tile then color filter instead of color filter then tile.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. An image filter is present along with a color filter?
    If the ImageFilter and ColorFilter work together, the ColorFilter will be applied first and then the ImageFilter will be applied. And as of now, all ColorFilter will absorb opacity, so I think in this scenario, the performance of this PR will be correct.

  2. An advanced blend + a color filter is being used?
    Since advanced blend is still applied after ColorFilter, there will be no problem

So I think this PR is correct.

@bdero bdero requested a review from ColdPaleLight January 31, 2023 18:17
Copy link
Member

@ColdPaleLight ColdPaleLight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jonahwilliams jonahwilliams added the autosubmit Merge PR when tree becomes green via auto submit App label Feb 1, 2023
@auto-submit auto-submit bot merged commit 97d27ff into flutter:main Feb 1, 2023
auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Feb 2, 2023
…119765)

* 4b77e7793 [Impeller] improve blur performance for Android and iPad Pro. (flutter/engine#39291)

* 97d27ff59 [Impeller] let images with opacity and filters passthrough. (flutter/engine#39237)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

autosubmit Merge PR when tree becomes green via auto submit App e: impeller

Projects

No open projects
Archived in project

Development

Successfully merging this pull request may close these issues.

[Impeller] texture passthrough for opacity isn't general enough

4 participants