Closed Bug 1809081 Opened 2 years ago Closed 2 years ago

Custom COLRv1 font to override flag emojis makes Firefox freeze

Categories

(Core :: Layout: Text and Fonts, defect)

Firefox 108
x86_64
Windows 11
defect

Tracking

()

VERIFIED FIXED
110 Branch
Tracking Status
relnote-firefox --- 109+
firefox-esr102 --- unaffected
firefox108 --- wontfix
firefox109 + verified
firefox110 + verified

People

(Reporter: julien.marcou.dev, Assigned: jfkthame)

References

(Regression)

Details

(Keywords: regression)

Attachments

(1 file)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0

Steps to reproduce:

I tried to used the "Noto Color Emoji" font from Google (COLRv1 format), to override the emojis on Windows (because Windows doesn't support real flag emojis), the performance is great, but as soon as I try do display many flag emojis, Firefox completly freezes.

I created a custom emoji picker (repository & demo available on GitHub: https://github.com/Julien-Marcou/unicode-emoji-picker-demo), so to reproduce the bug, you can:

  • go to https://emoji.julien-marcou.fr/
  • change the font from "System's Default" to "Noto Color Emoji"
  • see how every tabs (except the "Flags" tab) are super smooth, no freeze, no rendering issue
  • you can also try to go on the "Search an Emoji" tab and scroll down fast, everything will be smooth until the flags get loaded, the entire viewport will freezes for several frames
  • you can also try to resize the window when on the "Flags" tab and see Firefox struggling to repaint/reflow everything on screen

My best guess is that because Firefox is already overriding the flag emojis on Windows, there may have some conflicts between the Firefox override and the "Noto Color Emoji" override.

It also looks like some flags are making Firefox freeze event more, while debugging I tried to display only some flags, and the 🇦🇫 (flag of Afghanistan) seems harder to render for Firefox than other flags, may be the complexity of the emoji doesn't help.

Actual results:

When overriding the font of the browser with "Noto Color Emoji", rendering many flag emojis on screen makes Firefox freeze.

Expected results:

Firefox should not freeze (it works perfectly on Chrome, Edge, and even Safari with the SBIX format instead of the COLRv1 format).

OS: Unspecified → Windows 11
Hardware: Unspecified → x86_64

Here is a video showing the bug: https://youtu.be/-AqQ1sRDV5k

I was able to reproduce this issue as well in Firefox Release, Beta as well as our latest Nightly build, however In ESR builds the Flag emojis are not displayed for some reason. I was able to get a regression range for this issue.

11:25.32 INFO: Last good revision: 1e106796d80a09440185e4d5bcdd431e28dea125
11:25.32 INFO: First bad revision: b3b91aca9d8b140a69a8333a9d57f6c90d2ef4a4
11:25.32 INFO: Pushlog:
https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=1e106796d80a09440185e4d5bcdd431e28dea125&tochange=b3b91aca9d8b140a69a8333a9d57f6c90d2ef4a4

It seems that Bug 1791558 which enabled these fonts is whats causing it.
@jfkthame Can you please take a look at this issue ?

Severity: -- → S3
Status: UNCONFIRMED → NEW
Component: Untriaged → Graphics: Text
Ever confirmed: true
Flags: needinfo?(jfkthame)
Product: Firefox → Core
Regressed by: 1791558
Component: Graphics: Text → Layout: Text and Fonts

Here's a profile: https://share.firefox.dev/3it09yc

We're spending lots of time drawing glyphs on the CPU, on the content process... It seems most of the time is just getting glyph bounds. We're also drawing using WebRender fallback.

On Linux it seemed to be faster.

This shouldn't change visible behavior, but it makes painting glyphs
that have many layers under a PaintComposite operation -- some of the
Noto flag glyphs have hundreds of layers! -- substantially faster by
avoiding the need to explicitly walk the paint graph to determine the
temporary surface bounds.

On my local Windows build, this reduces the "jank" of first-time
switching to the flags page of the example from 2400ms to around 900ms;
still a bit sluggish but greatly improved. Subsequently switching away
from and back to the flags, the jank reduces to around 110ms.

(Interestingly, the perf issue here seems to be much worse on Windows
than on macOS or Linux; apparently getting glyph paths via DirectWrite
is more expensive than on the other platforms.)

Assignee: nobody → jfkthame
Status: NEW → ASSIGNED
Pushed by jkew@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/af4783d6e0de
Pass overall glyph bounds into COLRv1 paint methods if available, to avoid the need for on-the-fly bounding box computation in PaintComposite. r=gfx-reviewers,lsalzman
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 110 Branch

This issue is Verified as fixed in our latest build 110.0a1 (2023-01-15).

Flags: needinfo?(jfkthame)

What are your thoughts on uplifting this to release for next week's scheduled dot release?

Flags: needinfo?(jfkthame)

I think the risk of any regressions here is pretty minimal, and the fix was verified on 110 and no issues have shown up. So I'd be OK with uplifting it, if you think it's justified. But I don't feel all that strongly about it; while the performance is poor in the example here, it's not an actual failure; after a couple seconds the content renders as expected.

Presumably the affected font (Noto Color Emoji) may be present by default on newer Linux and Android systems, which means those users would benefit from the fix, though at least on Linux the perf issue looked less severe than on Windows. (Windows uses will only be affected if they have independently installed the Noto font, or if a site deploys it as a webfont; the standard platform fonts aren't significantly affected.)

Flags: needinfo?(jfkthame)

Comment on attachment 9312157 [details]
Bug 1809081 - Pass overall glyph bounds into COLRv1 paint methods if available, to avoid the need for on-the-fly bounding box computation in PaintComposite. r=#gfx-reviewers

Beta/Release Uplift Approval Request

  • User impact if declined: Poor performance (potential multi-second jank) when many Noto Color Emoji font glyphs (esp. flags) are rendered. (Comment 9 for details.)
  • Is this code covered by automated tests?: Yes
  • Has the fix been verified in Nightly?: Yes
  • Needs manual test from QE?: No
  • If yes, steps to reproduce:
  • List of other uplifts needed: None
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): Simple change to avoid recomputing surface bounds at each stage of compositing; no change in behavior/correctness, only performance.
  • String changes made/needed:
  • Is Android affected?: Yes
Attachment #9312157 - Flags: approval-mozilla-release?

[Tracking Requested - why for this release]:
Poor performance (esp. on Windows) with Noto Color Emoji font: the page may appear to hang for as much as several seconds.

Comment on attachment 9312157 [details]
Bug 1809081 - Pass overall glyph bounds into COLRv1 paint methods if available, to avoid the need for on-the-fly bounding box computation in PaintComposite. r=#gfx-reviewers

Approved for 109.0.1

Attachment #9312157 - Flags: approval-mozilla-release? → approval-mozilla-release+

This issue is Verified as fixed in our latest Release 109.0.1 (64-bit) .

Status: RESOLVED → VERIFIED

Added to the 109.0.1 relnotes:

Fixed jank when loading pages containing a large number of emoji characters

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: