thread-safe access to font metrics

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

thread-safe access to font metrics

Bobby Holley-2
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?

(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.

Thanks,
bholley
_______________________________________________
dev-tech-layout mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-layout
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: thread-safe access to font metrics

Jonathan Kew
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
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-layout
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: thread-safe access to font metrics

Bobby Holley-2
Thanks Jonathan!

I think as a first pass it makes sense to just stick all the font stuff
behind a lock (which we only acquire from workers). If it shows up in
profiles, we can figure out which paths we want to make thread-safe.

On Wed, Dec 14, 2016 at 6:01 AM, Jonathan Kew <[hidden email]> wrote:

> 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
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-layout
Loading...