Split from ticket:385#comment:20
This affects all platforms, with or without opengl rendering. See screenshot:
Probably a regression since I must have tested transparency when it was added to webp, but 0.10.x is also affected.
shows the artifacts on transparent windows when using webp
Transparency support was added in r3522, and works ok as I expected. r3884, r4245 and r5091 don't change any of the actual encoder code, so the problem must come from somewhere else..
Bisecting:
So the problem comes from r4151, likely to be in the argb code, I tested byteswapping on RGB components, but maybe it's the (un)premultiply codepath..
This is a regression, needs to be in 0.11
Taking out the line:
return byte_buffer_to_buffer(unpremultiply_argb(img_data))
And returning the data as it is instead (premultiplied), the picture looks OK (albeit, with too much in the alpha channel)
What I don't understand is why this affects webp
and not the other encodings, which also use the same codepath!? (ie: png
via PIL
also gives us a string buffer)
Since webp is buggy and not going to be used by default (and maybe we should even disable it?), re-scheduling this ticket until after #491
re-scheduling all webp stuff
The problem: webp
's simple API returns unpremultiplied alpha, which is not what we want and when we unpremultiply it again, it goes out of range... not sure about Pillow (the version in Fedora 20 does not seem to be able to decode webp
..)
So, we have to:
webp
codec module, so we can get unpremultiplied alpha just like with the other encodings
webm
(and Pillow?) decoded picture options (which will still be used as fallback), so the window backings will know it is unpremultiplied already... some backigns will skip the unpremultiply step, and the opengl case will re-premultiply it!
webp
from the list of encodings when using opengl without the advanced api decoder
Note: the corruption is not directly visible with the opengl backing because we now use the premultiplied alpha directly during rendering (it may just end up oversaturated instead)
And... to make matters worse, webp
decides if the picture has an alpha channel not using any API flags, but by inspecting the alpha component of every pixel in the input and deciding that if any values are not 0xFF
then it is on.. WTH? And whose bright idea was this?
clamp rgb values when unpremultiplying to prevent overflow
Implemented a new "advanced API" webp
decoder in r6509:
buffer
type in r6508
python-webm
and Pillow
)
I'm not going to bother fixing the codepath for the other decoders (I have not tested to see if Pillow
uses premultiplied alpha or not), you will just get the wrong transparency levels with those. (and eventually, maybe we should just drop them)
r5510 clears out the alpha channel before calling the webp
Encode
function, not very efficient but it works.
Ready for testing. Related to #419.
afarr: please check that webp
works as primary encoding:
transparent_colors.py
test script (transparency is only supported on Linux clients and must be compared with running native on Linux without xpra - beware, the bug is a fairly subtle difference)
Encoding_Info.exe
: dec_webp
and enc_webp
at {{0.4.0}}}
webp
data we receive on the client does not contain any alpha when we don't want any: run the client with -d webp
and you should see webp decompress found features: ... has_alpha=0
(has_alpha=1
when alpha is present)
h264
..), even at fairly high resolution (the code should switch to more suitable encodings rather than crawl to a halt - see #419 for details)
Important note: because of #419, the actual encoding used for each region of pixels we send may end up being different from the one we specify. The only way to verify what encoding is used is to turn on compression debugging with -d compress
on the server and to manually verify what comes out.
Note: I am not applying the attachment/ticket/487/argb-clamp.patch because it would actually hide any overflow, and we want to see it and fix it instead.
(re-assign)
Tested with Windows 7 - 64 bit, Windows 8.1 - 32 bit, and Fedora 20 - 64 bit:
transparent_colors.py
local and through xpra with and without opengl, both looked identical (xpra and locally running), as far as I could tell
dec_webp
and enc_webp
as 0.4.0
transparent_colors.py
transparent_colors.py
Of note, using both Windows and Fedora clients, running a high definition youtube video full screen with webp causes the framerate to slow down to a crawl. Otherwise, everything worked as expected.
Thanks for testing, this reminds me of just how slow webp
can be (see #419): it falls off a cliff in lossless mode, especially at low speed and at high resolutions (1080p and up). So I'll run some more tests tomorrow to ensure that we never use it as a temporary non-video encoding with those problematic combinations of options (this should already be the case, but best to triple check).
What was the resolution you tested at when fullscreen? 1080p? If so, unless you have other options set, it should have switched to high speed which should still be faster than png
. Having xpra info
of when it is really slow may help me figure things out.
Re-tested some more today, and made some more tweaks (r6528, r6534, r6535), fixes (r6529, r6531) and improvements to the test code (r6530, r6532, r6533).
Closing.
Note: in 0.14, the old python-webm
is completely removed in favor of the new webp
advanced codec, see r6555.
this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/487