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

Replaced Paint.setAlpha() with Paint.setColor() to reduce unnecessary allocations #1929

Merged
merged 3 commits into from
Nov 17, 2021

Conversation

pablorengo
Copy link
Contributor

Resolves #1928

This pull request attempts to remove ColorSpace.Named[] allocations when calling Paint.setAlpha(). These changes will fix the issue only when using RGB colors.

@@ -161,7 +162,12 @@
return;
}
int alpha = (int) ((parentAlpha / 255f * ((IntegerKeyframeAnimation) opacityAnimation).getIntValue() / 100f) * 255);
paint.setAlpha(clamp(alpha, 0, 255));
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
int color = paint.getColor();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

getColor() could generate the same allocations as setAlpha() if the color is not RGB.

@LottieSnapshotBot
Copy link

Snapshot Tests
28: Report Diff

1 similar comment
@LottieSnapshotBot
Copy link

Snapshot Tests
28: Report Diff

@gpeal
Copy link
Collaborator

gpeal commented Nov 3, 2021

@pablorengo I'm not seeing the same behavior as you. I tried your repro project (thank you for that, by the way) on API 30 and 31 and am not seeing any allocations other than the autoboxing Integer for the dynamic properties.

This seems to be the ColorSpace.values() call you're referring to but it is only called once ever so I'm not sure where the behavior you're seeing is happening.

@pablorengo
Copy link
Contributor Author

pablorengo commented Nov 3, 2021

@gpeal Sorry, I forgot to mention it here too. This problem happens on API level <= 29. It was fixed on Android 30 code.

This is the problem on Android 29. The ColorSpace.get() is called for every frame of the animation when Paint.setAlpha() is called.

@gpeal
Copy link
Collaborator

gpeal commented Nov 3, 2021

@pablorengo Lottie uses LPaint() which already has an optimization for text locale. This could be upstreamed to that so that it applies everywhere, not jus for strokes and fills.

@pablorengo
Copy link
Contributor Author

@gpeal Great. Let me check it and I'll come back with the modification. Thanks.

@gpeal
Copy link
Collaborator

gpeal commented Nov 12, 2021

@pablorengo Are you still interested in doing this?

@pablorengo
Copy link
Contributor Author

@gpeal Yes, I'll try to finish it today

@LottieSnapshotBot
Copy link

Snapshot Tests
28: Report Diff

@LottieSnapshotBot
Copy link

Snapshot Tests
28: Report Diff

int alpha = (int) ((parentAlpha / 255f * opacityAnimation.getValue() / 100f) * 255);
paint.setAlpha(clamp(alpha, 0, 255));
paint.setColor((clamp(alpha, 0, 255) << 24) | (color & 0xFFFFFF));
Copy link
Collaborator

Choose a reason for hiding this comment

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

@pablorengo You can revert this now right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gpeal In this case, it avoids calling setColor() twice.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah, I see. Got it. We could also make setColorAndAlpha on LPaint in case there are other usages of this in the future

@@ -35,4 +38,13 @@ public LPaint(int flags, PorterDuff.Mode porterDuffMode) {
public void setTextLocales(@NonNull LocaleList locales) {
// Do nothing.
}

@Override public void setAlpha(int alpha) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you add a doc explaining why this is necessary so future people can understand?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's not a "memory issue". It's avoiding memory allocations.

int alpha = (int) ((parentAlpha / 255f * opacityAnimation.getValue() / 100f) * 255);
paint.setAlpha(clamp(alpha, 0, 255));
paint.setColor((clamp(alpha, 0, 255) << 24) | (color & 0xFFFFFF));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah, I see. Got it. We could also make setColorAndAlpha on LPaint in case there are other usages of this in the future

@LottieSnapshotBot
Copy link

Snapshot Tests
28: Report Diff

@LottieSnapshotBot
Copy link

Snapshot Tests
28: Report Diff

@gpeal gpeal merged commit 9e92081 into airbnb:master Nov 17, 2021
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.

Calling Paint.setAlpha() generates several ColorSpace$Named[] allocations
3 participants