[cairo] fixing Cairo's FreeType multi-threaded usage
David Turner
david at freetype.org
Wed Feb 28 14:06:33 PST 2007
Hello,
here's the first version of my patches to fix Cairo's usage of FreeType with multiple
threads. It's rather big, so I'll summarize things here a little:
- it's more or less a complete rewrite of the functionality, but it is
API and ABI compatible with the original code.
- there is no need to modify any client code, except the one using the broken
cairo_ft_scaled_font_lock_face() and cairo_ft_scaled_font_unlock_face(),
which probably means only Pango at the moment.
normal users of Cairo should now be lock-free in all FreeType-related operations.
no need for thread-specific list and other hacks like that by the way.
- even if you use cairo_ft_scaled_font_lock_face() and cairo_ft_scaled_font_unlock_face(),
you should be free from deadlocks with the rest of Cairo. that's because the returned
FT_Face objects are allocated into a different library instance than the one used by
the rest of the library.
Of course, all hell breaks loose if two threads use FT_Face objects returned by
cairo_ft_scaled_font_lock_face() at the same time, even if they're not the same
FT_Face.
The upgrade path to sanity is to use the functions named:
cairo_freetype_state_lock()
cairo_freetype_state_get_face()
cairo_freetype_state_get_size()
cairo_freetype_state_unlock()
defined and documented in the new file cairo-freetype-state.c
- there are now two backends: a FreeType-specific one, and a FontConfig-specific one.
the only difference is that the FontConfig one is capable of implementing the
toy interface, and is thus still the default on Unix.
the idea is to be able to compile the FreeType backend on platforms where FontConfig
is not available or desirable. Of course, the toy interface would then be implemented
by the default backend for the platform, or simply not at all.
- there are thus two additionnal public header files: "cairo-freetype.h" and
"cairo-fontconfig.h", with corresponding functions using the surprisingly long
"cairo_freetype_" and "cairo_fontconfig_" prefixes
- this was done to avoid any conflict with the existing code and public headers.
"cairo-ft.h" is still there and its functions are fully supported even if we
can't make thread-safety guarantees for "locked" FT_Face usage.
- the source code "cairo-ft-font.c" is still there, but is not compiled anymore.
this is essentially for comparison purposes.
- there are quite a few new source files as well:
cairo-freetype-state.c (thread-safe FT_Face/FT_Size management)
cairo-freetype-font.c (FreeType font backend)
cairo-freetype-glyph.c (glyph loading + rendering + filtering)
cairo-freetype.h (public FreeType backend APIs)
cairo-freetype-private.h (guess what)
cairo-fontconfig.h (public FontConfig backend APIs)
cairo-fontconfig.c (tiny FontConfig font backend)
cairo-ft.c (stubs to implement original cairo_ft_ functions)
- I'd be happy to use shorter prefixes like "cairo_ft_" and "cairo_fc_" once
Carl is happy with the implementation provided here. I wanted to be able to
easily compare the new and the old code, and the different prefixes just
makes things a lot easier there.
- the cairo_ft_ functions do implement the current Cairo behaviour regarding
font options (i.e. the FontConfig backend ignores user-provided options for
antialiased setting, extracting those from the original FcPattern instead)
since I still don't understand why this is a good thing, the cairo_freetype_
and cairo_fontconfig_ equivalent functions to do implement this "feature",
but this can easily be changed.
(I plan to make a different email to discuss this issue in more details)
- there is also a RATIONALE file that explains how certain things are implemented,
that should make understanding the changes easier
Finally, all test cases pass, except the ft-text-vertical-layout-* ones, but
I believe it's because I don't have the relevant font files installed on my
machine. Will check later.
There has been a lot of shuffle during the intermediate commits that led to this
patchset, so I recommend only studying the final changes, instead of the individual
ones.
Voila, you can find all this here:
http://david.freetype.org/cairo/fix-freetype-usage-1.patchset.bz2
http://david.freetype.org/cairo/RATIONALE
Hope this helps,
- David Turner
- The FreeType Project (www.freetype.org)
More information about the cairo
mailing list