[cairo] Counting semantics of cairo_ft_scaled_font_lock_face
David Turner
david at freetype.org
Tue Feb 13 03:02:39 PST 2007
On Mon, 12 Feb 2007 12:20:57 -0800, "Carl Worth" <cworth at redhat.com> said:
> The work to remove those impacts probably wouldn't even be too
> severe. Though it's also not obvious to me if the impact is all
> negative. For example, might it not be better to maintain two separate
> FT_Face objects rather than thrashing back and forth with
> FT_Set_Transform on a shared FT_Face?
>
there are several problems there:
- first of all, a FT_Face object can be very large. Even when
memory-mapping the font file, each one can take between 20 and
250 KB (the latter is for multi-megabytes CJK fonts) of
heap memory. I try to reduce these numbers in each new release
of the library, but it's not always easy to do so without
sacrificing performance or even binary compatibility with
programs that access font engine internals directly (which I
hope are rapidly disappearing).
The worst offenders in this regards are Type 1 fonts and compressed
pcf/bdf fonts, which is one of the reasons why I'd like to get rid
of these ugly formats :-) However, this can be even noticeable with
TrueType/OpenType fonts, depending on their design.
this memory is never shared between processes, so it can add
up pretty quickly on a typical desktop. Think about 30
processes linked to Cairo, each one implementing its own cache
of 16 FT_Face objects, plus its own glyph cache in heap memory.
that's also exactly why FT_Size objects exist in the first place;
each FT_Size holds state information related to a given
character pixel sizes. By default, each FT_Face has a FT_Size,
but you can create more FT_Size for the same FT_Face in order
to save memory. And FT_Size objects are much smaller than
a FT_Face (around 4-8 KB, the first FT_Size is accounted for
in the size of the FT_Face).
Also, switching between FT_Size objects (with FT_Activate_Size)
is in certain cases a lot faster than calling FT_Set_Char_Size
since it avoids recomputing many things (especially when the
TrueType bytecode interpreter is used)
It's true that FT_Set_Transform changes a FT_Face field, instead
of a FT_Size one. That's probably my fault, but this isn't a
real issue due the second point below.
- second, you assume that concurrent operations on two distinct
FT_Face is not a problem. This is unfortunately totally
untrue, since there are things shared internally by several objects
especially to reduce the total heap usage of the library.
For example, I guarantee you that you could encounter ugly race
conditions when loading/rasterizing glyphs from two distinct
FT_Faces from two distinct threads at the same time.
The only correct way to use concurrent faces without locking in
the client is to create each one of them in its own FT_Library,
and then, your heap usage is going to increase significantly.
And I want to be able to share even more data between these
FT_Face objects in the future, all for the sake of memory
footprint reduction.
FreeType has never been designed to be used concurrently by
multiple threads; locking from the client is required. And this
feature has not, and will not, been pushed into the library for
several good reasons.
Hope this helps,
- David Turner
- The FreeType Project (www.freetype.org)
More information about the cairo
mailing list