[cairo] cairo-gl glyph rendering performance
Bill Spitzak
spitzak at gmail.com
Mon May 2 12:57:59 PDT 2011
I'm pretty certain that for some operations, in particular OVER, drawing
the glyphs atop each other produces identical results to compositing
them together and then doing an a single operation.
Pixel has color B, and and OVER operation is drawn with color C of two
glyphs, first one with opacity a and second with b:
result= (B(1-a)+Ca)(1-b)+Cb
= (B-Ba+Ca)(1-b)+Cb
= B-Ba+Ca-Bb+Bab-Cab+Cb
= B(1-a-b+ab)+C(a+b-ab)
If instead we composite a and b first we get a+b-ab. Using this with
color C we get:
result= B(1-(a+b-ab))+C(a+b-ab)
= B(1-a-b+ab)+C(a+b-ab)
= the first result
I suspect this is true for several of the other operators. It would
certainly be worth it to make a list and avoid this for these
Chris Wilson wrote:
> On Wed, 20 Apr 2011 01:30:58 +0300, Alexandros Frantzis <alexandros.frantzis at linaro.org> wrote:
>> Hi all!
>>
>> I have been investigating the cairo-gl glyph implementation to see if we
>> can improve the glyph rendering performance.
>>
>> I have found that one source of performance loss is the overzealous selection
>> of the "via mask" path when rendering glyphs. When using the "via mask" path,
>> glyphs are first rendered to a temporary surface which is then used as a mask
>> to draw the glyphs on the final destination.
>>
>> In the current code, one of the reasons to use the mask path is because the
>> glyphs overlap. Is this valid?
>
> Yes. It is deeply engrained in the API that a single operation acts a
> single mask. If the overlapping glyphs of the glyph string were to be
> rendered individual then you would operate twice on the overlapping
> pixels. Hence why we need to go construct a mask for the entire string to
> a apply it as a single operation.
>
>> In any case, the overlap detection test as implemented in
>> _cairo_scaled_font_glyph_device_extents() is not suited for our needs for two
>> reasons:
>
> We know. Applying the KISS rule to avoid over-engineering.
>
>> 1. The overlap detection algorithm checks the extents of each glyph against the
>> current total extent of previously processed glyphs. This works fine as long
>> as the glyph group is limited to a single line and drawn sequentially.
>
> This is the *extremely* common case due to historical interface
> limitations i.e. code that has evolved from using X interfaces or through
> pango will perform line breaking.
>
>> 2. Due to font kerning, glyphs extents are often found to be overlapping,
>> although the glyphs themselves are not actually overlapping.
>
> Right, this is relatively common, about 25% of cases in ff, iirc.
>
>> The important question here is how can actually achieve using the "via mask"
>> path less. Can we remove the overlap factor completely? Assuming that not using
>> a mask is wrong, how wrong are the results going to be? If the visual
>> difference is small enough perhaps we can make this compromise to increase
>> performance (or use an environment variable and leave it to the user to force
>> the fast behavior).
>
> No, the visual result is wrong and text output is one that people care
> immensely about. The performance you measured is about 5-10x slower than
> what can be achieved using an intermediate mask (guestimating based on the
> i965 timings). So the extra step is not the bottleneck per-se.
>
> Once I no longer feel embarrassed by the ddx performance, I'll gladly
> embarrass mesa instead.
> -Chris
>
More information about the cairo
mailing list