Render conformance

David Reveman c99drn at cs.umu.se
Tue Sep 14 04:29:40 PDT 2004


On Wed, 2004-09-08 at 13:10 -0700, Aaron Plattner wrote: 
> Keith,
> 
> I've been looking at our RenderAccel conformance, and I have a couple of
> questions/comments:
> 
> 1. On 2004-08-30 Eric Anholt changed the transformed coordinates test in
>    rendercheck so that it shifts the image by 1/2 pixel in both directions.
>    This seems wrong to me.  Shouldn't the default filtering be to use
>    whatever pixel the transformed coordinate falls inside?
> 
> 2. The protocol spec is somewhat ambiguous about what "component alpha"
>    really means, and the Porter/Duff paper isn't much help either. 

Having the RENDER protocol spec explain component alpha a bit better
wouldn't hurt. For what it's worth, here's my explanation of how it's
suppose to work:

If [Mr, Mg, Mb, Ma] are the components of a component alpha mask picture
and [Sr, Sg, Sb, Sa] are the components of a source picture, then if
[Ar, Ag, Ab, Aa] are the components of the intermediate alpha result and
[Cr, Cg, Cb, Ca] are the components of the intermediate color result
from the "src IN mask" part of the general compositing operation, they
should be computed like this:

Ar = Mr * Sa
Ag = Mg * Sa
Ab = Mb * Sa
Aa = Ma * Sa

Cr = Mr * Sr
Cg = Mg * Sg
Cb = Mb * Sb
Ca = Ma * Sa

With these different color and alpha components for each channel, the
destination components [Dr, Dg, Db, Da] should be computed like this:

Dr = Cr * Fa + Dr * Fb
Dg = Cg * Fa + Dg * Fb
Db = Cb * Fa + Db * Fb
Da = Ca * Fa + Da * Fb

Values of 'Fa' and 'Fb' should be computed separately for each channel
using [Ar, Ag, Ab, Aa] and the table in section 8 of the RENDER protocol
specification.

e.g. for the OVER operator 'Fa' and 'Fb' for the red channel will be:
Fa = 1
Fb = 1 - Ar

That should be it. 

(If someone finds a problem with this explanation please let me know, as
if this is wrong, glitz is probably also doing the wrong thing)

>    Our
>    understanding was simply that the color channels of the mask are used to
>    modulate the source image before it is composited with the destination.
>    The server (and rendercheck) instead use the mask as a separate alpha
>    component for each channel.  

One of the ideas with component alpha is to be able to use compositing
for sub-pixel rendered graphics and I don't think that there's any
simpler way to do that than the above explanation.

I've noticed that component alpha doesn't work very well with NVIDIA's
RenderAccel and by looking at the output, I kind of got the idea that
you were doing something like a simple modulate.

I simple modulate wont work as it will not respect the alpha component
of the source, hence using a translucent source will produce very
incorrect results and the blending is also wrong as the same alpha value
is used for all color components.

> This doesn't match any of OpenGL's (or
>    D3D's) blending operations and is very difficult to accelerate in
>    hardware.  Other drivers don't seem to support it either, and Glitz has
>    to resort to several passes with glColorMask to achieve the same thing.

yes, it seems to be really hard to accelerate. 

What I've done with glitz is that I've got a general way for doing
component alpha that works with all different porter/duff operators and
all combinations of source and mask images. This is done using one pass
per component and works fine but performance is of course as what you
can expect from such a multi-pass algorithm. The trickiest part of this
method is to, using OpenGL's standard texturing environment, get the
red, green and blue color components of the mask replicated to the alpha
component so that blending will be correct. I'm able to do that with the
functionality provided by GL_ARB_texture_env_dot3.

However, if the source image is a solid image (1x1 with repeat) and the
porter/duff operator is OVER, glitz can do component alpha a lot more
efficiently. This is done by modulating the component alpha mask with
the solid image's alpha value and then use the following blending
function instead of the normal 'OVER' blend function:

glBlendFunc (GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);
with blend color set to the unpre-multiplied color of the solid image.

This is great as it allows glitz to render sub-pixel glyphs using solid
colors at pretty much the same speed as normal compositing operations
with a single source, and as I think about 99% of all glyphs rendered on
todays desktops are done using solid colors this is very useful.

I could probably add support for some other porter/duff operators but
don't know how useful that would be.

BTW, you can find a few screenshots that shows the problem with
component alpha and NVIDIA's RenderAccel here:
http://www.cs.umu.se/~c99drn/pics/rendertest/ , and if you like you can
grab a copy of the rendertest program used for those screenshots from
cairo CVS: http://www.cairographics.org/download .
 
-David




More information about the xorg mailing list