[OpenJDK 2D-Dev] Handling of premultication in the D3D & OGL pipelines
campbell at plausible.coop
Wed Oct 2 22:48:46 UTC 2013
I haven't looked at the code in question in quite a while, but my recollection is that the OGL (and D3D) pipelines treated all surfaces -- including opaque ones -- as premultiplied because the OpenGL blend modes weren't flexible enough to replicate the equations used in our software loops. I seem to recall taking advantage of the lack of a strict specification for this particular case and I made the OGL pipeline do whatever would allow for the fastest rendering, even if that meant it didn't produce exactly the same results as the software loops.
Just like Jim, I remember some break-room discussion as to what the "correct" behavior should be for this case, but I don't think we reached a conclusion. I think there might even have been a bug report filed that talks about these discrepancies, but I can't seem to fi… Oh, wait, here's something!
That seems to align with what Jim and I remember, but unfortunately it doesn't go into too much detail about the "analysis" the ensued, and my memory's not getting any younger either :D
On Oct 2, 2013, at 3:03 PM, Jim Graham <james.graham at oracle.com> wrote:
> From looking at the code, it looks like this is probably a bug. The default color model for TYPE_INT_RGB is non-premultiplied which means that we should have unmultiplied the alpha before we stored the color. Now, if you had used an alpha of 0, then we would have been unable to reverse any pre-multiplication step and the results would have been undefined for practical reasons, but with an alpha even as low as 2, we should have been able to reverse the multiplication to something other than black.
> It looks like the bug is in the PixelConverter.Xrgb class which just returns the raw rgb value (misnomer, it is actually an argb value) as the pixel without checking the pre-multiplied flag of the colormodel. We should probably have an XrgbNonPre and XrgbPre to be more accurate.
> At some point, I seem to recall discussions about our handling of premultiplication for opaque surfaces and we realized that we were not doing it quite right, and I seem to recall throwing our hands up in frustration but I don't remember why we didn't clean this up (gettin' too old now...) :(
> On 9/30/13 10:52 PM, Clemens Eisserer wrote:
>> I am currently testing compatibility of the xrender pipeline with
>> different composition operations, and I noticed for AlphaComposite.SRC
>> the D3D and OGL pipelines store pre-multiplied colors in surfaces
>> without an alpha-channel.
>> For example the following code results in a black rectangle, instead
>> of a red one when rendering to a BufferedImage of type INT_RGB:
>> ((Graphics2D) g).setComposite(AlphaComposite.Src);
>> g.setColor(new Color(255, 0, 0, 2));
>> g.fillRect(10, 10, 100, 100);
>> Is this intentional or should it be considered a bug?
>> Thanks, Clemens
More information about the 2d-dev