Hi Bobby,
On 13/12/2016 17:34, Bobby Holley wrote:
Hi Jonathan,
For Stylo to compute values for 'ex' and 'ch' units, it needs access to
font metrics from the parallel worker threads. I've heard that font
metrics are generally not thread-safe in Gecko, so I'm trying to figure
out next steps, and have a few questions:
(1) How not-thread-safe is the font metric stuff? If we just need
trivial stuff like the things mentioned above, will we still run into
problems?
In principle, the answer may differ between font back-ends, as we
ultimately rely on platform APIs to access fonts. But I think the answer
is that font metric stuff -can- be made thread-safe without too much
difficulty.
My understanding is that both Core Text & Core Graphics on macOS and
DirectWrite & GDI on Windows can safely be used to read font metrics
from multiple threads.
Note, however, that the FreeType docs say that "[a]n ‘FT_Face’ object
can only be safely used from one thread at a time", so multiple
concurrent workers all asking for metrics may be problematic on Linux
and Android.
The current Gecko code in gfx/thebes that deals with metrics is -not-
thread-safe, however, as it includes a bunch of caching that looks like
it'd be unsafe (e.g. gfxGlyphExtents includes an nsTHashtable where it
stores extents, and this would get very confused if two threads
simultaneously tried to update it). We could presumably go through that
code and make it thread-safe (for some cost), if that would be an
overall win.
(Actually, you're probably less interested in gfxGlyphExtents at this
stage; that would be relevant to textRun construction rather than style
processing. But initializing the metrics of an individual gfxFont object
is also not thread-safe, AFAICS.)
(2) Assuming that the information we need does indeed require
non-threadsafe calls, can you tell us whether those calls are strictly
main-thread-only, or whether it's enough to simply avoid concurrency? We
block the main thread during style traversal, so we could stick a mutex
around the font metrics stuff and only acquire that mutex during
parallel traversal (leaving main-thread callpaths untouched). We could
then also cache the metrics we need in TLS to further-reduce the
synchronization cost.
I'm not aware of any main-thread-only calls involved here; I believe
you'll be fine getting metrics on a worker thread. The two issues we'll
need to be careful of are the currently non-thread-safe caching in
gfxFont etc., and the FreeType restriction on concurrent use of an
FT_Face. If we make the gfxFont caching thread-safe, then AFAIK you
could have multiple concurrent threads getting font metrics on both
macOS and Windows.
Besides getting metrics, I suspect you're also going to be interested in
querying the list of available fonts (so that you can find the best
matching face for a given family/weight/stretch/style/etc combination).
That will also need to be looked at, because the current Gecko font-list
code loads the faces within each family lazily (and modification of the
gfxFontFamily to add faces isn't thread-safe).
So really, this comes before the question about font metrics: you can't
get font metrics until you know which font you're dealing with, so you
need to resolve the font-* properties to a specific face, and currently
you can't safely do that concurrently from multiple threads. (AFAIK it
should be OK to do it from a single worker thread if the main thread is
blocked.)
HTH,
JK
_______________________________________________
dev-tech-layout mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-layout