| Summary: | [Regression 2.0.12] Alpha value of 0 on INDEX8 format surfaces is opaque | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Jason Borden <jasonborden79> |
| Component: | video | Assignee: | Sylvain <sylvain.becker> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | major | ||
| Priority: | P2 | CC: | icculus |
| Version: | HG 2.0 | Keywords: | target-2.0.14 |
| Hardware: | x86_64 | ||
| OS: | Linux | ||
| Attachments: | Test INDEX8 alpha program | ||
The affecting code is in src/video/SDL_surface.c starting around line 1033. I understand considering a surface to be opaque if all palette values are 255 (SDL_ALPHA_OPAQUE), but why also consider it opaque if there's any 0 (SDL_ALPHA_TRANSPARENT)? Sylvain, I think this is related to changes you made for 2.0.12? Yes, this is from previous fixes, maybe a wrong assumption! I think this is related to whether a palette is considered RGB or RGBA. The explanation: Images with xpm format are often represented with a palette, and there are loaded as index8. (it's also possible to get/create index8 palette differently). Sometimes the palette has a no alpha at all (for each entries, the alpha field is 0), but it's not a fully transparent image. It's a RGB, just no alpha channel, and we have to detect it here: https://hg.libsdl.org/SDL/file/9a8e6854f652/src/video/SDL_surface.c#l1030 https://hg.libsdl.org/SDL/file/9a8e6854f652/src/render/SDL_render.c#l1166 The current implementation is short and does that in 1 loop + break: It says by default it's RGB, but if there is an alpha value != 0 and != 255, it becomes ARGB. So a palette with entries that are both 0 or 255 are still RGB. Another implementation could be : by default it's ARGB, but if all alpha fields are 255 it becomes RGB or if all alpha fields are 0 it becomes RGB Maybe this is wrong, and should be changed, what do you think Sam? I can also comment the code here: https://hg.libsdl.org/SDL/file/9a8e6854f652/src/video/SDL_surface.c#l1054 Blitting using a palette with alpha=0 doesn't work, if we want a RGB blit. We need to detect and temporarily patch the palette, by setting alpha=255. This is the "if (set_opaque)" block. If there is a real alpha value, the loop is "break'ed" and set_opaque is set to false. (https://hg.libsdl.org/SDL/file/9a8e6854f652/src/video/SDL_surface.c#l1042 ) (In reply to Sylvain from comment #3) > So a palette with entries that are both 0 or 255 are still RGB. This is my exact scenario. Index 0 is transparent(0) and all other indices are opaque(255). > Another implementation could be : > by default it's ARGB, > but if all alpha fields are 255 it becomes RGB > or if all alpha fields are 0 it becomes RGB This solution would fix my problem and still solve your other issue I think. Ok, thanks I fixed this here: https://hg.libsdl.org/SDL/rev/b68bc68d5cce added SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel) to detect whether the palette is fully opaque or not, and it if has an alpha channel. all alpha 0 -> it's opaque without alpha channel all alpha 255 -> it's opaque with alpha channel otherwise it's not opaque, and it has an alpha channel I replayed a few test-cases of bug 3827, also your! Can we mark this bug resolved now, or is there still some problem after Sylvain's patch? I have verified that my issue has been fixed, but I'm not sure if Sylvain wanted to do any more testing before closing the issue. It seemed ok for me, so I mark this as fixed! |
Created attachment 4259 [details] Test INDEX8 alpha program In 2.0.12 and latest hg snapshot (2.0.13-13624) INDEX8 type surfaces that use a 0 alpha value in their palette will not be transparent like versions 2.0.5 - 2.0.10. Attached is a test program that shows this bug. On versions 2.0.5 - 2.0.10 a green window will be displayed for 10 seconds. On 2.0.12 or 2.0.13-13624 it will show a white window for 5 seconds then a green window for 5 seconds.