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

Displaylist ColorFilter objects #31491

Merged
merged 8 commits into from
Feb 17, 2022

Conversation

flar
Copy link
Contributor

@flar flar commented Feb 16, 2022

Fixes flutter/flutter#98715

This PR creates an inspectable object for DisplayLists to store ColorFilters. These objects can also be stored inline in the DisplayList buffer of records without requiring a dangling pointer that needs to be searched and freed when a DL is disposed.

The class can implement any of the ui.ColorFilter objects used in Dart ui code, and can recapture any of those ColorFilter types from an SkColorFilter as well for when we need to recapture rendering ops from code that only speaks to an SkCanvas (for the time being just the Paragraph code).

This PR can be compared and contrasted to the previous PR which accomplished this objective by creating a number of different DL records and Dispatcher.setFooColorFilter(args) methods. It feels a bit simpler to have these DlColorFilter objects instead of the plethora of dispatch methods. This PR also provides a ready storage format for keeping a shared DlColorFilter* reference where needed.

@flar
Copy link
Contributor Author

flar commented Feb 16, 2022

I'll need to wait for the associated changes in flutter/impeller#12 to be merged before I can update the DEPS file so that these changes will compile.

@flar flar force-pushed the displaylist-colorfilter-objects branch from 789ee11 to 9969ac4 Compare February 16, 2022 19:35
@flar flar requested a review from dnfield February 16, 2022 20:44
@@ -390,7 +391,7 @@ class DisplayListBuilder final : public virtual Dispatcher,
void onSetBlender(sk_sp<SkBlender> blender);
void onSetShader(sk_sp<SkShader> shader);
void onSetImageFilter(sk_sp<SkImageFilter> filter);
void onSetColorFilter(sk_sp<SkColorFilter> filter);
void onSetColorFilter(const DlColorFilter* filter);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any reason to not use a shared_ptr here? Even, for example, a shared_ptr?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we do that, then when the dispatcher wants to dispatch the op from the record in the DL, it has to reinstantiate the object.

Alternately, I suppose I could back off to storing the shared_ptr in the buffer, but then equals and destructor have to visit each node and manually compare or manually destruct. One of my goals was to embed the info directly in the DL buffer so that we could mass compare and mass free the buffers.

}

std::shared_ptr<DlColorFilter> shared() const override {
return std::make_shared<DlBlendColorFilter>(this);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why isn't this unsafe? Each call to this will create new shared pointers that don't know about each other. One of them could end up dangling.

Copy link
Contributor Author

@flar flar Feb 17, 2022

Choose a reason for hiding this comment

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

make_shared(...) calls the constructor on T that matches the args. It returns a shared_ptr to a brand new instance of the DlColorFilter (DlBlendColorFilter in that particular case).

shared()->get() != this
*shared()->get() == *this

Perhaps I should add tests for that first condition to the unittests?

Copy link
Contributor Author

@flar flar Feb 17, 2022

Choose a reason for hiding this comment

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

My concept was that the DlFoo objects would be lightweight, immutable, and copyable without loosing any functionality. This function takes advantage of those design constraints.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only unsafe (perhaps surprising) aspect of this method is that the address in the shared_ptr will not be the address of the original. That might be unexpected, but I don't think this is unsafe wrt memory management and since the objects are immutable, it shouldn't be unsafe with respect to sharing modifications.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added those unit tests to verify that the shared ptr returned is distinct from the original.

@flar
Copy link
Contributor Author

flar commented Feb 17, 2022

I added a bunch of comments to the d_l_color_filter header with a design philosophy comment at the top and then method comments on the methods in the base class.

Copy link
Contributor

@dnfield dnfield left a comment

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

create a DisplayList ColorFilter object.
5 participants