[Pixman] Pixman glyph compositing

Bill Spitzak spitzak at gmail.com
Thu Jan 24 12:08:30 PST 2013


If these are individual glyphs I think you are going to have a problem 
if any glyphs extend outside the box defined by their escapement. Either 
these pixels will get clipped off, or portions of neighboring glyphs 
will get erased.

So I think you have to composite glyphs at some point as though they 
have transparent areas outside the ink.

However your idea could be used to then copy a temporary buffer 
containing all the glyphs to the final output as a 2-color image. The 
main advantage would be that the temporary buffer would be 1-channel 
rather than 3 or 4.

A plausable cairo api would be to be able to set the source to an image 
plus two colors which are the colors that 0 and 1 in that source image 
turn into. I think it has been proposed (or already exists?) that a 
"fade" color be able to be specified, this is used to render a colorized 
and partially transparent version of a source without another 
intermediate image. This would be the same as the 1 color, the 0 color 
would be a new addition.

The problem I see is that this probably adds a huge number of new 
compositing back-end functions. There would have to be variations 
depending on whether the source image is 1 or 3 or 4 channels, whether 
the colors are transparent, and for each compositing operation.

David Herrmann wrote:
> 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
> _______________________________________________
> Pixman mailing list
> Pixman at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/pixman


More information about the Pixman mailing list