[Pixman] Pixman glyph compositing

David Herrmann dh.herrmann at googlemail.com
Wed Jan 23 11:50:18 PST 2013


Hi

While working on kmscon the main rendering task I am faced with is
blending a glyph into the main framebuffer with a constant foreground
and background color. The code I have been using is a per-pixel
blending operation on each color value:

For each pixel "i" I do:
  r = alpha[i] * foreground.r + (255 - alpha[i]) * background.r
  g = alpha[i] * foreground.g + (255 - alpha[i]) * background.g
  b = alpha[i] * foreground.b + (255 - alpha[i]) * background.b
  r /= 255;
  g /= 255;
  b /= 255;
  dst[i] = (r << 16) | (g << 8) | b;

So I have an 8bit alpha channel from the glyph as input and an xrgb32
output framebuffer. The 24bit foreground/background values are
constant during a single blending operation.

I already optimized this by special-casing alpha[i] == 0 or 255 and I
changed the division to 256 instead of 255. However, I was wondering
whether pixman can provide a better alternative. Unfortunately, the
fastest code I could come up with was (using shadow-buffer):

pixman_fill(shadow, background);
pixman_composite(OVER, foreground, alpha, shadow);
pixman_blt(shadow, dst);

I use a shadow buffer as I _really_ want to avoid to composite
directly into the hardware buffer (which is in most cases way slower
than the extra pixman_blt). However, this scenario requires writing
the data three times and even reading it during the composite
operation. But still, thanks to pixman-optimizations, this turns out
to be almost exactly as fast as my own trivial implementation. So I
was wondering whether anyone has ideas how to speed this up?

Is there a way to perform this operation with a single pixman call? If
not, are there any other optimizations I should consider?

The best renderer I could come up with creates an array with all
characters that need to be updated for the next frame and then does:

foreach(character as c) {
  foreach(line(c) as l) {
    foreach(alpha(l) as a) {
      dst[l, p] = composite(a, fg, bg);
    }
  }
}

And composite() does what I described above. This loop can also be found here:
https://github.com/dvdhrm/kmscon/blob/master/src/uterm_video_dumb.c#L371

I would be thankful for any hints how to optimize this.
Regards
David


More information about the Pixman mailing list