Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Impeller] Replace Impeller opacity peephole delegate with DL variant. #52707

Merged
merged 15 commits into from
May 31, 2024

Conversation

jonahwilliams
Copy link
Member

@jonahwilliams jonahwilliams commented May 10, 2024

Use the existing DL opacity peephole flags and remove the Impeller variant. Also wires up for experimental canvas.

Work towards flutter/flutter#142054

transform_stack_.back().distributed_opacity *= paint.color.alpha;
return;
} else {
FML_LOG(ERROR) << "no dist 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.

@flar try as I might, I can't seem to get this to fire on any of the opacity peephole tests in the macrobenchmarks app. It seems like can_distribute_opacity is always false with impeller?

This is just running with the regular canvas.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can't get which to fire? This is the "false" part of the if. Does this mean it is always true?

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 mean its never true

Copy link
Contributor

Choose a reason for hiding this comment

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

It's working for the dl_sk_dispatcher, though...?

Copy link
Contributor

Choose a reason for hiding this comment

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

(or we would have had benchmark regressions).

Copy link
Member Author

Choose a reason for hiding this comment

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

but its not working here :)

Is there something different in the impeller DL setup that we're missing for dl opacity peephole? or some other requirement I'm missing?

Copy link
Contributor

Choose a reason for hiding this comment

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

I was finally able to get this running locally and it worked for me with Grid with alpha SaveLayer on Rows

Copy link
Contributor

Choose a reason for hiding this comment

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

If you tell me which sub-test types you ran I can look and see why they don't do peephole optimizations. Keep in mind that I created buttons for scenarios that wouldn't work so that we had something to aim for in the future, so not every one of those options will result in opacity peephole success...

@jonahwilliams
Copy link
Member Author

Can confirm this is working, sorry for the noise!

@jonahwilliams jonahwilliams changed the title [Impeller] test DL opacity peephole. [Impeller] Replace Impeller opacity peephole delegate with DL variant. May 15, 2024
@jonahwilliams jonahwilliams marked this pull request as ready for review May 15, 2024 00:29
TRACE_EVENT0("flutter", "Canvas::saveLayer");
if (can_distribute_opacity) {
FML_DCHECK(!backdrop_filter);
Copy link
Member Author

Choose a reason for hiding this comment

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

@flar I'm surprised but I hit this check in some tests. Do I need to assume that even if can_distribute_opacity is true, there may be other paint states (blend mode/ filters) that can still require a save layer?

Copy link
Contributor

Choose a reason for hiding this comment

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

Which tests? I can take a look and see if there might be something wrong with the DL checks. In particular, I think I only pass SrcOver for now even though other blend modes might cause problems. I disallow ColorFilters, but I allow ImageFilters because according to my investigations the opacity should be applied to the output of the ImageFilter so it shouldn't matter. (It's applied to the input of the ColorFilter, though, so I just disallow them even though I could maybe look at their details and find that some of them are compatible).

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, are you specifically referring to backdrop filter vs opacity flag? I notice that I don't turn off the flag in that case, but perhaps I should. The flag is more about the contents and whether the contents are compatible.

I also don't think I check the attributes that apply the SL to the parent. If they aren't SrcOver then I don't think we can do the opacity stuff.

I also don't believe the "old code" (pre-reorg) does this either. Let me get the reorg back in and then I can revisit layer properties and how they affect the flag.

Copy link
Contributor

Choose a reason for hiding this comment

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

Entity::TileMode::kClamp);

// Paint has image filter, can't elide.
delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
Copy link
Contributor

Choose a reason for hiding this comment

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

This might be the case where I differ in assumptions. DL allows IF+opacity, but it looks like AIKS expects it to be disallowed...?

Copy link
Member Author

Choose a reason for hiding this comment

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

We always fold the opacity into the image filter compositing, so in effect its as if the peephole wasn't applied.

paint.color = Color::Red();

// Paint has no alpha, can't elide;
delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
Copy link
Contributor

Choose a reason for hiding this comment

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

Huh? Why can't opaque colors be peepholed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Just old overly defensive code.


// OpacityPeepholePassDelegate will only get used if the pass's blend mode is
// SourceOver, so no need to check here.
if (paint_.color.alpha <= 0.0 || paint_.color.alpha >= 1.0 ||
Copy link
Contributor

Choose a reason for hiding this comment

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

If the alpha is 0 then we should skip the pass entirely, so I'm not sure why it is saying that it "can't collapse into parent" here (i.e. return false).

Also, if the paint is opaque, then that isn't a reason not to collapse the pass...? It just means you have no partial opacity to distribute, but you can still collapse it and distribute the opacity of 1.0 (i.e. NOP on modifying the 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.

I think I was just being overly conservative at the time.

@chinmaygarde
Copy link
Member

Are we making progress on this?

@jonahwilliams
Copy link
Member Author

Need to get back to it and address feedback, but was waiting on the DL reorg patch to reland.

@flar
Copy link
Contributor

flar commented May 28, 2024

The reorg has rolled all the way now, so work depending on it should be good to go...

@jonahwilliams
Copy link
Member Author

@flar

The DL opacity peephole is still missing cases that the impeller version got in the wonderous app. On the main carosel view, both the clouds (while in motion only) and the swipe up indicator are impacted by impeller but not display list:

image

@flar
Copy link
Contributor

flar commented May 29, 2024

It looks like entities allow kSrc with opaque which DL doesn't allow. I'll look into supporting that, but I'll have to figure out how to emulate it in the Skia Dispatcher.

if (!((blend_mode_ == BlendMode::kSource && contents_->IsOpaque()) ||

@jonahwilliams
Copy link
Member Author

I don't think there are any src blend mode entities in this app, this check is supposed to help resolve the interactions between srcOver -> src promotion and opacity peephole

@jonahwilliams jonahwilliams requested a review from flar May 31, 2024 02:03
@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 #52707 at sha 49c7376

Copy link
Contributor

@flar flar left a comment

Choose a reason for hiding this comment

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

I think the inherited opacity doesn't transfer to a child SaveLayer's blit back, but maybe I'm misreading the changes...?

} else {
new_layer_pass.SetDelegate(std::make_shared<PaintPassDelegate>(paint));
}
new_layer_pass.SetDelegate(std::make_shared<PaintPassDelegate>(paint));
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this transfer the existing distributed opacity from the transform_stack.back() to the new layer pass?

Copy link
Contributor

Choose a reason for hiding this comment

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

Basically, if this saveLayer didn't pass along the distributed opacity above, then it needs to apply it to the blit-back to the parent and I don't see where that is happening. Should PaintPassDelegate carry along an extra parameter for the distributed opacity from outside the saveLayer?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch, this is fixed and a test case is added.

alpha.setColor(DlColor::kRed().modulateOpacity(0.5));

builder.SaveLayer(nullptr, &alpha);
builder.DrawRect(SkRect::MakeXYWH(000, 000, 100, 100), red);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are these XY numbers written as octal literals?

Also, don't they overlap? That should disable the group 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.

I... don't know. Call it a brain fart. Fixed.

@jonahwilliams jonahwilliams requested a review from flar May 31, 2024 16:55
alpha.setColor(DlColor::kRed().modulateOpacity(0.5));

builder.SaveLayer(nullptr, &alpha);
builder.DrawRect(SkRect::MakeXYWH(020, 020, 100, 100), green);
Copy link
Contributor

Choose a reason for hiding this comment

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

More octal numbers. Not an issue in this case, but I guess this is someone's way of lining up rows of numbers without the formatter complaining? Clever as long as you are aware that you are mising octal and decimal...

Copy link
Member Author

Choose a reason for hiding this comment

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

agh let me fix this too

Copy link
Contributor

@flar flar left a comment

Choose a reason for hiding this comment

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

LGTM

@flutter-dashboard
Copy link

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

Changes reported for pull request #52707 at sha 1f90efb

@jonahwilliams jonahwilliams added the autosubmit Merge PR when tree becomes green via auto submit App label May 31, 2024
@auto-submit auto-submit bot merged commit 21a8158 into flutter:main May 31, 2024
31 checks passed
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request May 31, 2024
auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Jun 1, 2024
…149462)

flutter/engine@990f1ce...40b868e

2024-05-31 jonahwilliams@google.com [Impeller] make strokes < 0.5 physical pixels visually thinner. (flutter/engine#53154)
2024-05-31 jonahwilliams@google.com [Impeller] Replace Impeller opacity peephole delegate with DL variant. (flutter/engine#52707)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC jacksongardner@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autosubmit Merge PR when tree becomes green via auto submit App e: impeller will affect goldens
Projects
None yet
3 participants