I’ve found some oddities with the reference implementation when blending with RGB565 surfaces. I tried the Rasteroid implementations to cross reference against, but they, unlike the reference implementation, don’t have any non-888 configs.
My example starts with a red square (1,0,0,1) on a white background (1,1,1,1). Overtop of this, I draw a transparent green line (0,1,0, 0.5).
The spec says “the source pixels are converted into the destination color space prior to blending” (p.131).
Yet blending modes “SRC” and “SRC_OVER” look different. The SRC_OVER one looks like the alpha value is used to blend with the destination color, while SRC is just solid green. (What do you do with the alpha value anyways when converting from 8888 to 565 anyways? Just discard it?)
So, assuming they values are NOT converted to the destination format prior to blending, I tried the non-PorterDuff modes and they ALL came out weird. With the same example of the green line over the red square on the white background, these are the results from vgReadPixel in sRBA8888 format.
Mode With Red With White
-----------------------------------------------------
Multiply 7B00 00FF 7BFF 7BFF
Screen FF82 00FF FFFF FFFF
Darken 7B00 00FF 7BFF 7BFF
Lighten 7B82 00FF FFFF FFFF
Additive 7B82 00FF FFFF FFFF
The way I read the spec, with Destination alpha hardcoded to 1, I see:
Multiply = (AsCs0 + 1Cd(1-As) + As1CsCd)/(As+1(1-As)) = Cd(1-As) + AsCsCd
…
Additive = (AsCs + 1Cd) /(min(As+1, 1)) = AsCs + Cd
Clearly, on additive blending for example, I’m not thinking the same way as the reference implementation, as I’d expect the color FF8000FF ontop of the red square.
Anyone has any insights?