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

Add support for tinting layer-backed ASDisplayNode #1617

Merged
merged 4 commits into from
Aug 15, 2019

Conversation

rahul-malik
Copy link
Contributor

Currently we're hitting an assertion on master because self.tintColor is read always within ASImageNode.mm. We would either ignore this and only allow tinting on view backed nodes but since we're drawing the contents it feels like we can extend this capability to layer backed nodes as well.

Copy link
Contributor

@bolsinga bolsinga left a comment

Choose a reason for hiding this comment

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

Thanks for the test!

Copy link
Member

@nguyenhuy nguyenhuy left a comment

Choose a reason for hiding this comment

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

Great diff! Excited to see that we can utilize the encapsulation provided by ASDisplayNode to support something CALayer doesn't. I have a couple of questions:

  • I'm wondering if we can implement this at a lower level (i.e ASDisplayNode) so that layer-backed ASTextNode and ASTextNode2 can support tint color too?
  • Now that layer-backed ASImageNode supports tint color, can we turn ASButtonNode’s image node back to be layer-backed (here)?

@rahul-malik rahul-malik changed the title Add support for tinting layer-backed ASImageNode Add support for tinting layer-backed ASDisplayNode Aug 14, 2019
Copy link
Member

@garrettmoon garrettmoon left a comment

Choose a reason for hiding this comment

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

Yay! Our designers will be so happy!

Source/ASButtonNode.mm Outdated Show resolved Hide resolved
@ghost
Copy link

ghost commented Aug 15, 2019

🚫 CI failed with log

#if TARGET_OS_IOS
// tvOS needs access to the underlying view
// of the button node to add a touch handler.
[_titleNode setLayerBacked:YES];
Copy link
Member

Choose a reason for hiding this comment

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

I know this is from the original impl, but the comment and the code don't add up. If the view is needed under tvOS, then this node should not be layer-backed under it (and can be layer-backed otherwise)?

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 comment might be misleading here, I think the intention was to gate this layer backing only for iOS and by doing nothing in tvOS it will automatically be view backed?

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 can make this clearer at least

if (_loaded(self)) {
if (_flags.layerBacked) {
// The first nondefault tint color value in the view’s hierarchy, ascending from and starting with the view itself.
return _tintColor ?: self.supernode.tintColor;
Copy link
Member

Choose a reason for hiding this comment

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

Our locking principles don't allow walking up the hierarchy while holding the node's lock. So you'd need to do it after releasing the lock.

if (![_tintColor isEqual:color]) {
_tintColor = color;
// Tint color has changed. Unlock here before calling subclasses and exit-early
AS::MutexLocker unlock(__instanceLock__);
Copy link
Member

Choose a reason for hiding this comment

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

This might not be safe because the MutexLocker (which basically is std::lock_guard) will try to unlock again when it's destroyed and yield an exception. Instead I think it'd be easier to just manage the lock manually (i.e remove _bridge_prologue_write and this line, and call lock/unlock directly on __instanceLock__.

Copy link
Member

@nguyenhuy nguyenhuy left a comment

Choose a reason for hiding this comment

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

LGTM!

[_titleNode setLayerBacked:NO];
#else
[_titleNode setLayerBacked:YES];
#endif
Copy link
Member

Choose a reason for hiding this comment

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

👍 Thanks for fixing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants