-
-
Notifications
You must be signed in to change notification settings - Fork 154
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
Fix segfault with antialiased draw functions with a depth different than 32bits #3008
Fix segfault with antialiased draw functions with a depth different than 32bits #3008
Conversation
edit : It doesn't fix |
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 tested locally. The segfault existed before, now it's gone. Visually it was broken before, now it's perfect.
LGTM, thanks for the fix! :)
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 left a few reviews. I'm a bit sceptical of the 24-bit codepath, which is also why I'm suggesting the tests to be stricter here.
This whole thing is a mess. Firstly, I would expect in a PR like this to see an explanation of what is actually being fixed, why it is segfaulting. Not just that it's fixed and needs tests from other users. You want to use SDL_GetRGBA correctly? See libsdl-org/SDL#8320 and libsdl-org/SDL@f8dfee0#diff-ec00a797fe34913f3e553761506783ef6b4cd0050704665615c93392ac7360e6R1557-R1618 They mention the performance is terrible "meant only for unittests", so that gets me thinking about performance: So get_antialiased_color is a performance sensitive function, why is it being called over and over decoding the value of original_color every single time? And so then this function produces a result to use in set_at, but set_at also calls SDL_GetRGB, but only on 24 bit! So in set_at it's taking a mapped color, unmapping it with SDL_GetRGB, then manually remapping it with bit shifting. Am I reading that right? (EDIT: PR to fix set_at to not call SDL_GetRGB every pixel: #3021) P.S. maybe we can do our version of SDL_GetRGBA "manually inlined" into our source by grabbing it from the SDL source. |
Hello, first, thank you for the constructive review ! Sorry, I forgot to mention what was the culprit behind this segfault. As you guessed, the problem resided on how we were extracting pixels in You suggested me to look at how SDL does the same work with |
So I see you checked out the SDL implementation and put it in, nice! The big endian build is failing though since you have a discrepancy in variable names. I found another way to get around this problem that may be better. When I looked through draw.c I saw that this is the only location that does any pixel reading, everything else is just doing pixel writing. But there are places in pygame-ce doing pixel reading, how are they doing it? I found in surface.h there's a macro Anyways, I'd be interested in seeing you check it out. |
I checked how it's done on other files, and I saw that they all used a switch case, and manually shift bits for 3 bytes case, and ultimately call |
Yes, I wasn't saying it avoided calling that function? Just saying that we already have an implementation strategy for calling that function properly, maybe that's the way to go here as well. |
What about adding a new C API function called |
To move this fix as close as possible to being merged. I'm doing some performance tests (just a little skeptical about the perf behind a lot of |
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.
Just a question
src_c/draw.c
Outdated
SDL_GetRGBA(pixels[(y * surf->w) + x], surf->format, &background_color[0], | ||
|
||
Uint32 pixel = 0; | ||
size_t bpp = surf->format->BytesPerPixel; |
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.
bpp = PG_SURF_BytesPerPixel(surf);
for SDL3 compatibility.
Why is this a size_t?
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.
Nice work changing surf->w to surf->pitch.
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.
Why is this a size_t?
Good question, I can't remember what i was thinking about when I used size_t
. Switching to int
.
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 approved and all, but just for the record you didn't switch to int.
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.
Sorry I forgot, now It's updated.
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.
Thanks!
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.
LGTM, thanks for the PR 😎
Closes #3008
This segfault also happens with antialiased functions from
pygame.draw
.Needs some tests from other users