[Pixman] [PATCH] spans

Chris Wilson chris at chris-wilson.co.uk
Sat Aug 20 12:54:20 PDT 2011

Taekjun Kim made a good suggestion on how to eliminate the majority of
the noise in the previous patch: simply handle opacity by first combining
(mask IN opacity) in the general_composite_rect. The rest of the patch is
then updating the internal API to propagate an opacity value from the new
public interface.

After a couple of weeks of work on the consumer of that public API, I've
concluded that the minimal interface of adding a single opacity value that
is equivalent to a mask is the simplest and yet complete enough for use by
cairo to implement clipped shapes with an unbounded operator with no less
efficiency than for bounded operations. (For the unbounded case, we create
a second compositor using OUT_REVERSE with WHITE and select the compositor
based on a bit in the span that indicates whether that span is
inside/outside the shape.)

Performing a pre-combine pass for opacity does measurably degrade
performance over implementing new opacity combiners (2% total time in
replaying a HTML5 canvas benchmark) - but the goal is not to hit the
general path at all! :)

I suspect that spans in their current form may prove hard to optimise
since the typical length of each non-opaque run will only be a pixel, with
the interior hitting the current opaque fast paths. (The exception to the
rule here is the prevalence of misaligned horizontal lines which includes
many benchmarks.) In theory, the true benefit then is this gives Cairo the
ability to implement single pass polygon fill, and speed up diagonal lines!
However, with only a fast C-path it is often faster to build an a8 mask and
then do a single SSE2 path than to operate with spans:

nearly-horizontal (dy of 1 pixel), 1 pixel wide lines:
          32      64    128    256    512
2-pass:  5206   5618   5971   6097   6967
1-pass:  8382   9115   9619   9528  10538

nearly-vertical (dx of 1 pixel), 1 pixel wide lines:
          32      64    128    256    512
2-pass:  8551   9164  14394  25218  50863
1-pass:  9283  13919  23135  42923  90104

diagonal (dx == dy), 1 pixel wide lines:
           32      64    128    256     512
2-pass:   8437  13077  24981  55254  153142
1-pass:  11898  18897  33314  61741  118610

(us, all measured on an Arrandale i7-640).

More information about the Pixman mailing list