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

Make the filter_ in mutator shared_ptr #34944

Merged

Conversation

cyanglaz
Copy link
Contributor

Storing raw filter_ pointers of DlImageFilter in union caused some issue where all the pointers are pointing to the same address in the stack.

This PR moves the filter_ object out of union so we can simply making the filter_ a shared_ptr.
This is to unblock flutter/flutter#43902
The real fix for Mutators should be: flutter/flutter#108470

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See testing the engine for instructions on
    writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Sorry, something went wrong.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
@cyanglaz cyanglaz requested review from JTKryptic and flar July 27, 2022 20:05
@cyanglaz cyanglaz marked this pull request as ready for review July 27, 2022 20:05
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.

Just a couple of nits about unnecessary calls to shared() in places that don't need them. You should only have to call "shared()" when you initially accept the DlImageFilter& reference into the system and after that just keep sharing/transferring/using the same shared_ptr.

@@ -56,7 +56,7 @@ class Mutator {
alpha_ = other.alpha_;
break;
case kBackdropFilter:
filter_ = other.filter_;
filter_ = other.filter_->shared();
Copy link
Contributor

Choose a reason for hiding this comment

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

For the copy constructor you can just copy the shared_ptr without having to recreate it with the shared() method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What do you mean by copy the shared_ptr?

Copy link
Contributor

Choose a reason for hiding this comment

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

filter_ = other.filter_

Why do you call shared() there? You already have a shared_ptr.

Copy link
Contributor Author

@cyanglaz cyanglaz Jul 27, 2022

Choose a reason for hiding this comment

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

Does filter_ = other.filter_ deep copy the raw pointer inside the shared_ptr? The idea of this copy constructor is that the filters are different objects, changing the value of the original filter will not affect the value of the copied filter.

Copy link
Contributor

Choose a reason for hiding this comment

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

No deep copy. It points to a new filter. It no longer points to the old filter.

@@ -119,15 +119,18 @@ class Mutator {
private:
MutatorType type_;

// TODO(cyanglaz): Remove union.
// https://github.com/flutter/flutter/issues/108470
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the SkPath object guaranteed to survive the lifecycle of the mutator? It might be safer to copy the SkPath using a copy constructor since the SkPath copy constructor is documented to be very fast and copy-safe.

Copy link
Contributor

Choose a reason for hiding this comment

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

https://api.skia.org/classSkPath.html#aa30a9363d49c092958d48e30608df367

The SkPath object is 16 bytes I think so the object takes up similar room to SkRect and much less than SkRRect or SkMatrix.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is the SkPath object guaranteed to survive the lifecycle of the mutator? It might be safer to copy the SkPath using a copy constructor since the SkPath copy constructor is documented to be very fast and copy-safe.

Yeah storing a copy of SkPath is fine with me, but I think shared_ptr for all the them is probably more consistent and fast/light weight too.

Copy link
Contributor

Choose a reason for hiding this comment

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

SkPath is kind of its own shared_ptr for all of the data that matters...

@@ -98,7 +98,7 @@ class Mutator {
case kOpacity:
return alpha_ == other.alpha_;
case kBackdropFilter:
return *filter_ == *other.filter_;
return *filter_ == *other.filter_->shared();
Copy link
Contributor

Choose a reason for hiding this comment

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

No need to call shared here as far as I can tell...?

@cyanglaz
Copy link
Contributor Author

Updated per review comments. @flar PTAL

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, you might want to run it by @chinmaygarde or @jason-simmons as some of the places you copy the shared_ptr might benefit from an "std::move" which will avoid unnecessary inc/decreffing.

@cyanglaz
Copy link
Contributor Author

The same filters are also used to filter none-PlatformView contents so I don't think std::move would be safe. Using std::move will make the code to be dependent on making sure the none-PlatformView part is done with the filter before passing the filter to the stack.

@cyanglaz cyanglaz added the autosubmit Merge PR when tree becomes green via auto submit App label Jul 27, 2022
@auto-submit auto-submit bot merged commit bbd1997 into flutter:main Jul 27, 2022
@cyanglaz cyanglaz deleted the mutator_stack_image_filter_out_of_union branch July 27, 2022 23:52
@flar
Copy link
Contributor

flar commented Jul 27, 2022

The same filters are also used to filter none-PlatformView contents so I don't think std::move would be safe. Using std::move will make the code to be dependent on making sure the none-PlatformView part is done with the filter before passing the filter to the stack.

It doesn't move the original. The call to your method already did one incref, a move macro just avoids a second incref/decref pair by "moving" your copy to the field. You hand off your ref to the field rather than create a new ref for the field and then drop your ref separately.

It's a very minor optimization if this code isn't used that often.

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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants