-
-
Notifications
You must be signed in to change notification settings - Fork 185
Optimized mask.from_surface()
when converting an alpha surface.
#2895
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
Optimized mask.from_surface()
when converting an alpha surface.
#2895
Conversation
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.
The work you do never ceases to amaze me. This works on my machine just fine.
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.
:pg_chad:
It had no effect when I posted it and I didn't test it locally to be sure it worked, even tho I trust that it does
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've tested locally with different sizes and I get a 65+% improvement for 32 bit surfaces and 10% with 16 bit surfaces, which is really impressive, good job!
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.
Also thinking more about it, I realised this probably breaks support for the more obscure kind of pixel formats (like say, SDL_PIXELFORMAT_ARGB2101010
or FOURCC style formats like YUV
) but the pygame codebase probably doesn't support these in other places to begin with, so we can let that slide for now
Co-authored-by: Ankith <itsankith26@gmail.com>
Co-authored-by: Ankith <itsankith26@gmail.com>
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.
Okay I am now satisfied that this PR should work for the common/normal cases.
Thanks for contributing! 🥳
…game-community#2895) * Optimized mask.from_surface when converting an alpha surface. * Fix issues wit 16-bit surfaces, tests for invalid threshold values * revert checks for threshold value * add comment and small refactor * fix * make fast path more generic * add early exit for threshold > 255 * Update src_c/mask.c Co-authored-by: Ankith <itsankith26@gmail.com> * Update src_c/mask.c Co-authored-by: Ankith <itsankith26@gmail.com> --------- Co-authored-by: Ankith <itsankith26@gmail.com>
This PR massively speeds up
mask.from_surface()
when dealing with the threshold argument (for 24 and 32 bit surfaces, about a 12% improvement for 16 and lower).It achieves so by directly accessing the pixel's alpha channels instead of using SDL's functionality which is not only slow but actually did more work that we actually need for this operation by also returning the rgb channels.
With this new strategy we just jump from pixel's alpha to pixel's alpha and check that against the threshold.
I've also added a fast path for 24-bit surfaces bringing an astonishing 737 times improved runtime since we now use
bitmask_fill
.I've also added a validity check for the threshold argument which wasn't there before.
here are the results:

made with this test program:
The data utils file (as txt):
data_utils.txt