Premultiplied vs non-premultiplied colors in solid and gradient pictures
keithp at keithp.com
Thu Jun 30 11:27:10 PDT 2005
On Thu, 2005-06-30 at 10:21 +0200, Lars Knoll wrote:
> On Thursday 30 June 2005 02:33, Keith Packard wrote:
> > I noticed that the change to the Render protocol has Solid pictures
> > using non-premultiplied values. That's inconsistent with all other
> > Render use of color and should be changed.
> The idea here was to make it consistent with gradients. It's rather confusing
> when some APIs take premultiplied, some take non premultiplied values (ok,
> FillRectangles also takes premultiplied).
Yes, it would be best to be consistent, but I don't know how to specify
gradients with only premultiplied colors. As I said, the 'right'
solution is to use five channels for gradient color specifications.
Perhaps we should just do that.
> Are super luminescent values supposed to be working? I'm don't think the code
> in fbcompose currently works correctly with them. Making it work correctly is
> easy, but will make the compositing operations quite a bit slower.
> I checked, and without supporting super luminescent values the C code expands
> to 25 assembler instructions, with support for them the code gets up to
> around 70 instructions, meaning it'll be a factor of 3 slower (I just did a
> short try and linear gradients on Xephyr get a factor of 2 slower, I'd expect
> a simple composite going through the code to suffer a bit more)
I don't understand this at all; you can't avoid supporting super
luminescent pixels if you have premultiplied colors for normal
compositing operations; the math 'just works'.
dst = src OVER dst:
dst = src + (1-alpha) dst;
The cost of doing the overflow check is only three instructions per
component, or 12 instructions total. And, as you mentioned, multi-media
instructions on almost any processor already know how to perform this
> > Non-premultiplied colors can contain color information for transparent
> > pixels.
> > For solids, the color information in a transparent pixel is irrelevant,
> > and so the 'one true' color definition here is premultiplied.
> One could argue this way :)
Jim Blinn makes a persuesive argument in his articles on compositing;
perhaps you have seen those? Premultiplied
colors provide for more efficient computation of intermediate results
that include alpha values as the natural result of the operations are
premultiplied and they require expensive division operations to convert
back to non-premultiplied, an operation which is not defined when the
computed alpha value is zero.
Plus, as already noted, they allow for a wider range of results, in some
real way making the operations 'complete' as you can get from one
intensity to any other with a suitable operand.
> It could be possible. But it think it might be confusing to the user (why do I
> need a separate A when I already have ARGB?) and make the API overly
> complicated. Isn't it enough to have just non premultiplied colors here?
It isn't sufficient to cover the compositing algebra that we'd like to
support, but it is sufficient to satisfy the SVG specification, which
does seem relevant.
And, of course, you could ignore either one of the alpha values by
simply setting them to one.
These five-value color gradients are even relatively easy to define --
you construct your gradient values by building two virtual surfaces, one
ARGB surface and one A surface and then performing an IN operation to
compute the gradient value at any particular point.
Obviously, a sensible implementation could notice when one or the other
A values were constant across the whole gradient and avoid interpolating
However, I also realize that we haven't figure out how to expose these
gradients to applications, and failing that, it's hard to see how
including support for them in the X server would help anyone right now.
So, I suggest that we just expose the non-premultiplied four-component
gradients that you've already implemented and we'll add other types in
the future once we figure out how they should work.
I think this means that the only change I'd like to see is to change the
representation of solid surfaces to pre-multiplied.
-------------- next part --------------
A non-text attachment was scrubbed...
Size: 189 bytes
Desc: This is a digitally signed message part
More information about the xorg