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

Reply via email to