-
Notifications
You must be signed in to change notification settings - Fork 6k
Use DlImageFilter for ImageFilterLayer #34837
Use DlImageFilter for ImageFilterLayer #34837
Conversation
e8f28df to
24450da
Compare
| return From(sk_filter.get()); | ||
| } | ||
|
|
||
| std::shared_ptr<DlImageFilter> makeWithLocalMatrix(const SkMatrix&) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to look into implementing this for real rather than just stubbing it out here. I think with this one addition to the DlImageFilter class hierarchy we can get rid of a few of the further uses of SkImageFilter down below.
I filed flutter/flutter#108263 for this with a fairly high priority. I'll look to try to address it in the next couple of days.
flow/layers/image_filter_layer.cc
Outdated
| PaintChildren(context); | ||
| context.leaf_nodes_builder->restore(); | ||
| } else { | ||
| cache_paint.setImageFilter(filter_ ? filter_->skia_object() : nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's try to standardize with just the Dl variant of this method as mentioned in the ColorFilter version of this PR. I realize that will mean implementing makeWithLocalMatrix which I'll put on a high priority.
| auto layer = std::make_shared<ImageFilterLayer>(sk_sp<SkImageFilter>()); | ||
| auto sk_image_filter = sk_sp<SkImageFilter>(); | ||
| auto layer = | ||
| std::make_shared<ImageFilterLayer>(DlImageFilter::From(sk_image_filter)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar comment as in the ColorFilter version of this PR. Unless a unit test has a specific reason to use one of the SkImageFilter variants that we don't support, migrate these to using a basic DlImageFilter object instead. I haven't looked through each and every unit test here, but I would be surprised if any of them actually care what kind of filter they are using (except some of their bounds answers might be tailored to the filter they originally chose and may need some adjustment to match a new type of filter.
|
@JsouLiang Are you interested in continuing with this PR? Moving to WIP since it sounds like @flar is requesting some bigger changes. |
That must have been a misunderstanding. There are no "bigger changes", this work is simply dependent on another mechanism being added under #34878 |
24450da to
daed8cd
Compare
flar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of kudos in the review comments, but at least one point of concern (the deleted line) and a couple of suggestions...
|
|
||
| SkRect child_bounds = SkRect::MakeEmpty(); | ||
| PrerollChildren(context, matrix, &child_bounds); | ||
| context->subtree_can_inherit_opacity = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this line deleted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It repeats with the next line
flow/layers/image_filter_layer.cc
Outdated
| context.leaf_nodes_builder->saveLayer(&child_paint_bounds(), | ||
| cache_paint.dl_paint()); | ||
| PaintChildren(context); | ||
| context.leaf_nodes_builder->restore(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(At some point we should probably create a new DL-based AutoSave object?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AutoSaveLayer support DisplayListBuilder
| image_filter_paint.setColor(opacity_alpha << 24); | ||
| image_filter_paint.setImageFilter(dl_image_filter.get()); | ||
| expected_builder.saveLayer(&child_path.getBounds(), | ||
| &image_filter_paint); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
flow/layers/layer.cc
Outdated
| } | ||
|
|
||
| Layer::AutoSaveLayer::~AutoSaveLayer() { | ||
| if (type_ == Type::kDisplayList) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we do checkerboarding? Ah, I see an issue. Another comment below would fix this...
flow/layers/layer.cc
Outdated
| if (type_ == Type::kDisplayList) { | ||
| dl_builder_->restore(); | ||
| return; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the following lines we always use canvas_ to checkerboard, but this could potentially be a nodes_canvas which would broadcast the checkerboarding to all embedded slices. We should probably always use leaf_canvas here regardless of the "mode" of the SkCanvas saveLayer.
dcaa63c to
09b18bc
Compare
09b18bc to
1b0d384
Compare
flar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My apologies for distracting this PR with the idea of a DisplayList AutoSaveLayer, let's not tackle that issue in this PR which should be about converting IFLayer to DlImageFilter.
| SkRect* map_local_bounds(const SkRect& input_bounds, | ||
| SkRect& output_bounds) const override { | ||
| if (!sk_filter_) { | ||
| return nullptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You must fill in output_bounds anyway per the contract of the method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should write a test to make sure that this happens.
|
There is something even more troubling about the DlAutoSaveLayer concept and even our existing DL-based saveLayers... They aren't executed on the internal_nodes_canvas which means they aren't propagated to other embedding layer canvas objects. There is a lot more thought to be done on how we're managing the saveLayer stack in the presence of DisplayListBuilders that goes far beyond this PR. For now, just continue with the same paradigm of using |
|
Sadly, it looks like this PR and the similar one for DlColorFilter introduced a bug. I haven't written any code to exploit it, but if we ever have a ColorFilterLayer or ImageFilterLayer that includes a PlatformView in its children then the filter will only apply to its pre-embedded children since we bypass the internal_nodes_canvas with the saveLayer calls. I think we have to revert the CF-de-skia-fying PR as well as hold off on this PR until we can come up with a new plan for how a post-Skia API world will deal with the stratifying of the layers due to embedded views. It isn't too hard to think "well, we can just convert everything to DisplayList and use a solution like flutter/flutter#109563 to replace it" but such a solution would impact our rendering using the Skia backend greatly as we would then be recording the scene into a DisplayList and playing it back to Skia rather than direct rendering to Skia. Until Impeller is our default rendering backend we'll have to make sure that our solution to this problem doesn't impact the Skia backend. |
|
Waiting for this #35421 to merge. |
f7a3cbf to
de1b257
Compare
flar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Now we can use DlImageFilter to replace SkImageFilter which can help us to enable some optimizations such as removing saveLayer objects for things like a matrix transform image filter on a compatible group of children.