[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