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

[Impeller] Reland of Simplify Advanced Blend color filters with a foreground color. #40927

Merged
merged 9 commits into from
Apr 10, 2023

Conversation

jonahwilliams
Copy link
Member

See previous revert: #40914

See original context in #40886

TLDR: the problem appears to be that my previous implementation only worked sort of by accident.

auto dst_uvs = maybe_dst_uvs.value();

auto size = rect_.size;
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
Copy link
Member Author

Choose a reason for hiding this comment

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

From reading render_filter, it appears that the coverage rect we are given already has the CTM applied. So we have two choices here: either directly use the values for the coordinates (and don't apply it to the MVP - or invert the transform and likewise.

Of course, if you don't invert the transform and fix the coordinates, then the UVs come out wrong and that's why I've "Fixed" them below.

I'm not sure exactly why this worked before

Copy link
Member Author

Choose a reason for hiding this comment

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

So there is some difference in a snapshot that is created by a contents, and a snapshot that is forwarded through from an entity pass. I'm tempted just to say, for this particular case, we should just set the UVs using the coverage rect, since that coverage rect already includes the CTM it is correct for both entity subpasses and for contents. But I'm still not really sure how I should be using the snapshot GetCoverageUVs directly which is concerning.

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess more of a question for @bdero, but what is the correct way to use snapshot.GetCoverageUVs ?

@jonahwilliams jonahwilliams marked this pull request as ready for review April 6, 2023 16:16
@flutter-dashboard
Copy link

Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change).

If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review.

Changes reported for pull request #40927 at sha f682b36

@chinmaygarde
Copy link
Member

cc @bdero to take a closer look. We should hold on landing this (if we are) till past the branch cut.

// This does not use the snapshot transform, since this value will
// be different depending on whether the filter was applied via a
// saveLayer or directly to a particular contents. By construction,
// the provided rectangle should exactly map to the texture coordinates.
Copy link
Member

@bdero bdero Apr 6, 2023

Choose a reason for hiding this comment

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

The transform of the snapshot needs to either be absorbed or deferred, otherwise this won't render correctly when the FilterInput decides to defer the transform and returns a non-identity matrix (TextureFilterInput or ContentsFilterInput holding a TextureContents sometimes defer their transforms to avoid unnecessary extra passes).

You can either absorb the snapshot transform by applying it to the positions (take the snapshot texture bounds and multiply by the transform) or draw the coverage rectangle and transform the texture coordinates instead (GetCoverageUVs computes the correctly transformed UVs for this).

Coverage rects and snapshot transforms computed by FilterInputs are already in screen space relative to the EntityPass texture position, and so the only difference between rendering into an inline subpass (current behavior of the blend filter) vs Contents::Render is that stuff rendered in a subpass needs to be shifted by the negative coverage origin (assuming the texture size is optimal), and then shifted back by pre-translating the transform in the returned Entity.

Copy link
Member Author

Choose a reason for hiding this comment

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

Got it, I took another look at this and found that I was more or less applying the origin offset twice since I was still appending the transform shift to the entity transform - which explained the difference.

This now uses getSnapshotUVs and renders correctly in both scenarios.

// to convert this back to a snapshot so it can be passed on. This generally
// implies that there is another filter about to run, so we'd perform this
// operation anyway.
auto potential_opacity = alpha.value_or(1.0) * dst_snapshot->opacity;
Copy link
Member Author

Choose a reason for hiding this comment

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

This seems like a reasonable thing to do?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I think this makes sense, although it'll probably just end up getting absorbed right away due to no filter being chained most of the time. Maybe we can come up with a mechanism to reconcile this later.

@jonahwilliams jonahwilliams requested a review from bdero April 7, 2023 18:25
Copy link
Member

@bdero bdero left a comment

Choose a reason for hiding this comment

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

LGTM.

Could we add a couple of simple goldens (non-interactive playgrounds) that hit these new foreground paths by blending a translated+rotated image input? Maybe one with absorbed alpha and one without? We should lightly cover all of the paths here eventually, but might as well cover new branches as they get added.

// to convert this back to a snapshot so it can be passed on. This generally
// implies that there is another filter about to run, so we'd perform this
// operation anyway.
auto potential_opacity = alpha.value_or(1.0) * dst_snapshot->opacity;
Copy link
Member

Choose a reason for hiding this comment

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

Yeah I think this makes sense, although it'll probably just end up getting absorbed right away due to no filter being chained most of the time. Maybe we can come up with a mechanism to reconcile this later.

@jonahwilliams
Copy link
Member Author

Yes, for this and the other filters I'll go through and add some goldens first.

Copy link
Member

@bdero bdero left a comment

Choose a reason for hiding this comment

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

Still LGTM

@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

Changes reported for pull request #40927 at sha 16734d2

@jonahwilliams
Copy link
Member Author

I think a 5 pixel diff is probably fine

@jonahwilliams jonahwilliams added the autosubmit Merge PR when tree becomes green via auto submit App label Apr 10, 2023
@auto-submit auto-submit bot merged commit 8850178 into flutter:main Apr 10, 2023
@jonahwilliams jonahwilliams deleted the pipeline_blend_simplify branch April 10, 2023 23:19
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Apr 10, 2023
zhongwuzw pushed a commit to zhongwuzw/engine that referenced this pull request Apr 14, 2023
…eground color. (flutter#40927)

[Impeller] Reland of Simplify Advanced Blend color filters with a foreground color.
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 will affect goldens
Projects
No open projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants