Bug 1848468 - Mark k-rate-dynamics-compressor-connections.html subtest as failing...
[gecko.git] / gfx / thebes / gfxPlatformMac.cpp
blobb71fe3345c8169fb7dc36d818ec2c46ecb701c4d
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "gfxPlatformMac.h"
8 #include "gfxQuartzSurface.h"
9 #include "mozilla/DataMutex.h"
10 #include "mozilla/gfx/2D.h"
12 #include "gfxMacPlatformFontList.h"
13 #include "gfxMacFont.h"
14 #include "gfxCoreTextShaper.h"
15 #include "gfxTextRun.h"
16 #include "gfxUserFontSet.h"
17 #include "gfxConfig.h"
19 #include "AppleUtils.h"
20 #include "nsTArray.h"
21 #include "mozilla/Preferences.h"
22 #include "mozilla/VsyncDispatcher.h"
23 #include "nsCocoaFeatures.h"
24 #include "nsComponentManagerUtils.h"
25 #include "nsIFile.h"
26 #include "nsUnicodeProperties.h"
27 #include "qcms.h"
28 #include "gfx2DGlue.h"
29 #include "GeckoProfiler.h"
30 #include "nsThreadUtils.h"
32 #ifdef MOZ_BUNDLED_FONTS
33 # include "mozilla/Telemetry.h"
34 # include "nsDirectoryServiceDefs.h"
35 # include "mozilla/StaticPrefs_gfx.h"
36 #endif
38 #include <dlfcn.h>
39 #include <CoreVideo/CoreVideo.h>
41 #include "mozilla/layers/CompositorBridgeParent.h"
42 #include "mozilla/layers/SurfacePool.h"
43 #include "VsyncSource.h"
45 using namespace mozilla;
46 using namespace mozilla::gfx;
47 using namespace mozilla::unicode;
49 using mozilla::dom::SystemFontList;
51 // A bunch of fonts for "additional language support" are shipped in a
52 // "Language Support" directory, and don't show up in the standard font
53 // list returned by CTFontManagerCopyAvailableFontFamilyNames unless
54 // we explicitly activate them.
55 static const nsLiteralCString kLangFontsDirs[] = {
56 "/Library/Application Support/Apple/Fonts/Language Support"_ns,
57 "/System/Library/Fonts/Supplemental"_ns};
59 /* static */
60 void gfxPlatformMac::FontRegistrationCallback(void* aUnused) {
61 AUTO_PROFILER_REGISTER_THREAD("RegisterFonts");
62 PR_SetCurrentThreadName("RegisterFonts");
64 for (const auto& dir : kLangFontsDirs) {
65 gfxMacPlatformFontList::ActivateFontsFromDir(dir);
69 PRThread* gfxPlatformMac::sFontRegistrationThread = nullptr;
71 /* This is called from XPCOM_Init during startup (before gfxPlatform has been
72 initialized), so that it can kick off the font activation on a secondary
73 thread, and hope that it'll be finished by the time we're ready to build
74 our font list. */
75 /* static */
76 void gfxPlatformMac::RegisterSupplementalFonts() {
77 if (XRE_IsParentProcess()) {
78 sFontRegistrationThread = PR_CreateThread(
79 PR_USER_THREAD, FontRegistrationCallback, nullptr, PR_PRIORITY_NORMAL,
80 PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
81 } else if (!nsCocoaFeatures::OnCatalinaOrLater()) {
82 // On Catalina+, it appears to be sufficient to activate fonts in the
83 // parent process; they are then also usable in child processes. But on
84 // pre-Catalina systems we need to explicitly activate them in each child
85 // process (per bug 1704273).
87 // But at least on 10.14 (Mojave), doing font registration on a separate
88 // thread in the content process seems crashy (bug 1708821), despite the
89 // CTFontManager.h header claiming that it's thread-safe. So we just do it
90 // immediately on the main thread, and accept the startup-time hit (sigh).
91 for (const auto& dir : kLangFontsDirs) {
92 gfxMacPlatformFontList::ActivateFontsFromDir(dir);
97 /* static */
98 void gfxPlatformMac::WaitForFontRegistration() {
99 if (sFontRegistrationThread) {
100 PR_JoinThread(sFontRegistrationThread);
101 sFontRegistrationThread = nullptr;
105 gfxPlatformMac::gfxPlatformMac() {
106 mFontAntiAliasingThreshold = ReadAntiAliasingThreshold();
108 InitBackendPrefs(GetBackendPrefs());
111 gfxPlatformMac::~gfxPlatformMac() { gfxCoreTextShaper::Shutdown(); }
113 BackendPrefsData gfxPlatformMac::GetBackendPrefs() const {
114 BackendPrefsData data;
116 data.mCanvasBitmask = BackendTypeBit(BackendType::SKIA);
117 data.mContentBitmask = BackendTypeBit(BackendType::SKIA);
118 data.mCanvasDefault = BackendType::SKIA;
119 data.mContentDefault = BackendType::SKIA;
121 return data;
124 bool gfxPlatformMac::CreatePlatformFontList() {
125 return gfxPlatformFontList::Initialize(new gfxMacPlatformFontList);
128 void gfxPlatformMac::ReadSystemFontList(SystemFontList* aFontList) {
129 gfxMacPlatformFontList::PlatformFontList()->ReadSystemFontList(aFontList);
132 already_AddRefed<gfxASurface> gfxPlatformMac::CreateOffscreenSurface(
133 const IntSize& aSize, gfxImageFormat aFormat) {
134 if (!Factory::AllowedSurfaceSize(aSize)) {
135 return nullptr;
138 RefPtr<gfxASurface> newSurface = new gfxQuartzSurface(aSize, aFormat);
139 return newSurface.forget();
142 void gfxPlatformMac::GetCommonFallbackFonts(uint32_t aCh, Script aRunScript,
143 eFontPresentation aPresentation,
144 nsTArray<const char*>& aFontList) {
145 if (PrefersColor(aPresentation)) {
146 aFontList.AppendElement("Apple Color Emoji");
149 switch (aRunScript) {
150 case Script::INVALID:
151 case Script::NUM_SCRIPT_CODES:
152 // Ensure the switch covers all the Script enum values.
153 MOZ_ASSERT_UNREACHABLE("bad script code");
154 break;
156 case Script::COMMON:
157 case Script::INHERITED:
158 // In most cases, COMMON and INHERITED characters will be merged into
159 // their context, but if they occur without any specific script context
160 // we'll just try common default fonts here.
161 case Script::LATIN:
162 case Script::CYRILLIC:
163 case Script::GREEK:
164 aFontList.AppendElement("Lucida Grande");
165 break;
167 case Script::MATHEMATICAL_NOTATION:
168 case Script::SYMBOLS:
169 case Script::SYMBOLS_EMOJI:
170 // Not currently returned by script run resolution (but see below, after
171 // the switch).
172 break;
174 // CJK-related script codes are a bit troublesome because of unification;
175 // we'll probably just get HAN much of the time, so the choice of which
176 // language font to try for fallback is rather arbitrary. Usually, though,
177 // we hope that font prefs will have handled this earlier.
178 case Script::BOPOMOFO:
179 case Script::HAN_WITH_BOPOMOFO:
180 case Script::SIMPLIFIED_HAN:
181 case Script::HAN:
182 aFontList.AppendElement("Songti SC");
183 if (aCh > 0x10000) {
184 // macOS installations with MS Office may have these -ExtB fonts
185 aFontList.AppendElement("SimSun-ExtB");
187 break;
189 // Currently, we don't resolve script runs to this value, but we may do so
190 // in future if we get better at handling things like `lang=zh-Hant`, not
191 // just resolving based on the Unicode text.
192 case Script::TRADITIONAL_HAN:
193 aFontList.AppendElement("Songti TC");
194 if (aCh > 0x10000) {
195 // macOS installations with MS Office may have these -ExtB fonts
196 aFontList.AppendElement("MingLiU-ExtB");
198 break;
200 case Script::HIRAGANA:
201 case Script::KATAKANA:
202 case Script::KATAKANA_OR_HIRAGANA:
203 case Script::JAPANESE:
204 aFontList.AppendElement("Hiragino Sans");
205 aFontList.AppendElement("Hiragino Kaku Gothic ProN");
206 break;
208 case Script::JAMO:
209 case Script::KOREAN:
210 case Script::HANGUL:
211 aFontList.AppendElement("Nanum Gothic");
212 aFontList.AppendElement("Apple SD Gothic Neo");
213 break;
215 // For most other scripts, macOS comes with a default font we can use.
216 case Script::ARABIC:
217 aFontList.AppendElement("Geeza Pro");
218 break;
219 case Script::ARMENIAN:
220 aFontList.AppendElement("Mshtakan");
221 break;
222 case Script::BENGALI:
223 aFontList.AppendElement("Bangla Sangam MN");
224 break;
225 case Script::CHEROKEE:
226 aFontList.AppendElement("Plantagenet Cherokee");
227 break;
228 case Script::COPTIC:
229 aFontList.AppendElement("Noto Sans Coptic");
230 break;
231 case Script::DESERET:
232 aFontList.AppendElement("Baskerville");
233 break;
234 case Script::DEVANAGARI:
235 aFontList.AppendElement("Devanagari Sangam MN");
236 break;
237 case Script::ETHIOPIC:
238 aFontList.AppendElement("Kefa");
239 break;
240 case Script::GEORGIAN:
241 aFontList.AppendElement("Helvetica");
242 break;
243 case Script::GOTHIC:
244 aFontList.AppendElement("Noto Sans Gothic");
245 break;
246 case Script::GUJARATI:
247 aFontList.AppendElement("Gujarati Sangam MN");
248 break;
249 case Script::GURMUKHI:
250 aFontList.AppendElement("Gurmukhi MN");
251 break;
252 case Script::HEBREW:
253 aFontList.AppendElement("Lucida Grande");
254 break;
255 case Script::KANNADA:
256 aFontList.AppendElement("Kannada MN");
257 break;
258 case Script::KHMER:
259 aFontList.AppendElement("Khmer MN");
260 break;
261 case Script::LAO:
262 aFontList.AppendElement("Lao MN");
263 break;
264 case Script::MALAYALAM:
265 aFontList.AppendElement("Malayalam Sangam MN");
266 break;
267 case Script::MONGOLIAN:
268 aFontList.AppendElement("Noto Sans Mongolian");
269 break;
270 case Script::MYANMAR:
271 aFontList.AppendElement("Myanmar MN");
272 break;
273 case Script::OGHAM:
274 aFontList.AppendElement("Noto Sans Ogham");
275 break;
276 case Script::OLD_ITALIC:
277 aFontList.AppendElement("Noto Sans Old Italic");
278 break;
279 case Script::ORIYA:
280 aFontList.AppendElement("Oriya Sangam MN");
281 break;
282 case Script::RUNIC:
283 aFontList.AppendElement("Noto Sans Runic");
284 break;
285 case Script::SINHALA:
286 aFontList.AppendElement("Sinhala Sangam MN");
287 break;
288 case Script::SYRIAC:
289 aFontList.AppendElement("Noto Sans Syriac");
290 break;
291 case Script::TAMIL:
292 aFontList.AppendElement("Tamil MN");
293 break;
294 case Script::TELUGU:
295 aFontList.AppendElement("Telugu MN");
296 break;
297 case Script::THAANA:
298 aFontList.AppendElement("Noto Sans Thaana");
299 break;
300 case Script::THAI:
301 aFontList.AppendElement("Thonburi");
302 break;
303 case Script::TIBETAN:
304 aFontList.AppendElement("Kailasa");
305 break;
306 case Script::CANADIAN_ABORIGINAL:
307 aFontList.AppendElement("Euphemia UCAS");
308 break;
309 case Script::YI:
310 aFontList.AppendElement("Noto Sans Yi");
311 aFontList.AppendElement("STHeiti");
312 break;
313 case Script::TAGALOG:
314 aFontList.AppendElement("Noto Sans Tagalog");
315 break;
316 case Script::HANUNOO:
317 aFontList.AppendElement("Noto Sans Hanunoo");
318 break;
319 case Script::BUHID:
320 aFontList.AppendElement("Noto Sans Buhid");
321 break;
322 case Script::TAGBANWA:
323 aFontList.AppendElement("Noto Sans Tagbanwa");
324 break;
325 case Script::BRAILLE:
326 aFontList.AppendElement("Apple Braille");
327 break;
328 case Script::CYPRIOT:
329 aFontList.AppendElement("Noto Sans Cypriot");
330 break;
331 case Script::LIMBU:
332 aFontList.AppendElement("Noto Sans Limbu");
333 break;
334 case Script::LINEAR_B:
335 aFontList.AppendElement("Noto Sans Linear B");
336 break;
337 case Script::OSMANYA:
338 aFontList.AppendElement("Noto Sans Osmanya");
339 break;
340 case Script::SHAVIAN:
341 aFontList.AppendElement("Noto Sans Shavian");
342 break;
343 case Script::TAI_LE:
344 aFontList.AppendElement("Noto Sans Tai Le");
345 break;
346 case Script::UGARITIC:
347 aFontList.AppendElement("Noto Sans Ugaritic");
348 break;
349 case Script::BUGINESE:
350 aFontList.AppendElement("Noto Sans Buginese");
351 break;
352 case Script::GLAGOLITIC:
353 aFontList.AppendElement("Noto Sans Glagolitic");
354 break;
355 case Script::KHAROSHTHI:
356 aFontList.AppendElement("Noto Sans Kharoshthi");
357 break;
358 case Script::SYLOTI_NAGRI:
359 aFontList.AppendElement("Noto Sans Syloti Nagri");
360 break;
361 case Script::NEW_TAI_LUE:
362 aFontList.AppendElement("Noto Sans New Tai Lue");
363 break;
364 case Script::TIFINAGH:
365 aFontList.AppendElement("Noto Sans Tifinagh");
366 break;
367 case Script::OLD_PERSIAN:
368 aFontList.AppendElement("Noto Sans Old Persian");
369 break;
370 case Script::BALINESE:
371 aFontList.AppendElement("Noto Sans Balinese");
372 break;
373 case Script::BATAK:
374 aFontList.AppendElement("Noto Sans Batak");
375 break;
376 case Script::BRAHMI:
377 aFontList.AppendElement("Noto Sans Brahmi");
378 break;
379 case Script::CHAM:
380 aFontList.AppendElement("Noto Sans Cham");
381 break;
382 case Script::EGYPTIAN_HIEROGLYPHS:
383 aFontList.AppendElement("Noto Sans Egyptian Hieroglyphs");
384 break;
385 case Script::PAHAWH_HMONG:
386 aFontList.AppendElement("Noto Sans Pahawh Hmong");
387 break;
388 case Script::OLD_HUNGARIAN:
389 aFontList.AppendElement("Noto Sans Old Hungarian");
390 break;
391 case Script::JAVANESE:
392 aFontList.AppendElement("Noto Sans Javanese");
393 break;
394 case Script::KAYAH_LI:
395 aFontList.AppendElement("Noto Sans Kayah Li");
396 break;
397 case Script::LEPCHA:
398 aFontList.AppendElement("Noto Sans Lepcha");
399 break;
400 case Script::LINEAR_A:
401 aFontList.AppendElement("Noto Sans Linear A");
402 break;
403 case Script::MANDAIC:
404 aFontList.AppendElement("Noto Sans Mandaic");
405 break;
406 case Script::NKO:
407 aFontList.AppendElement("Noto Sans NKo");
408 break;
409 case Script::OLD_TURKIC:
410 aFontList.AppendElement("Noto Sans Old Turkic");
411 break;
412 case Script::OLD_PERMIC:
413 aFontList.AppendElement("Noto Sans Old Permic");
414 break;
415 case Script::PHAGS_PA:
416 aFontList.AppendElement("Noto Sans PhagsPa");
417 break;
418 case Script::PHOENICIAN:
419 aFontList.AppendElement("Noto Sans Phoenician");
420 break;
421 case Script::MIAO:
422 aFontList.AppendElement("Noto Sans Miao");
423 break;
424 case Script::VAI:
425 aFontList.AppendElement("Noto Sans Vai");
426 break;
427 case Script::CUNEIFORM:
428 aFontList.AppendElement("Noto Sans Cuneiform");
429 break;
430 case Script::CARIAN:
431 aFontList.AppendElement("Noto Sans Carian");
432 break;
433 case Script::TAI_THAM:
434 aFontList.AppendElement("Noto Sans Tai Tham");
435 break;
436 case Script::LYCIAN:
437 aFontList.AppendElement("Noto Sans Lycian");
438 break;
439 case Script::LYDIAN:
440 aFontList.AppendElement("Noto Sans Lydian");
441 break;
442 case Script::OL_CHIKI:
443 aFontList.AppendElement("Noto Sans Ol Chiki");
444 break;
445 case Script::REJANG:
446 aFontList.AppendElement("Noto Sans Rejang");
447 break;
448 case Script::SAURASHTRA:
449 aFontList.AppendElement("Noto Sans Saurashtra");
450 break;
451 case Script::SUNDANESE:
452 aFontList.AppendElement("Noto Sans Sundanese");
453 break;
454 case Script::MEETEI_MAYEK:
455 aFontList.AppendElement("Noto Sans Meetei Mayek");
456 break;
457 case Script::IMPERIAL_ARAMAIC:
458 aFontList.AppendElement("Noto Sans Imperial Aramaic");
459 break;
460 case Script::AVESTAN:
461 aFontList.AppendElement("Noto Sans Avestan");
462 break;
463 case Script::CHAKMA:
464 aFontList.AppendElement("Noto Sans Chakma");
465 break;
466 case Script::KAITHI:
467 aFontList.AppendElement("Noto Sans Kaithi");
468 break;
469 case Script::MANICHAEAN:
470 aFontList.AppendElement("Noto Sans Manichaean");
471 break;
472 case Script::INSCRIPTIONAL_PAHLAVI:
473 aFontList.AppendElement("Noto Sans Inscriptional Pahlavi");
474 break;
475 case Script::PSALTER_PAHLAVI:
476 aFontList.AppendElement("Noto Sans Psalter Pahlavi");
477 break;
478 case Script::INSCRIPTIONAL_PARTHIAN:
479 aFontList.AppendElement("Noto Sans Inscriptional Parthian");
480 break;
481 case Script::SAMARITAN:
482 aFontList.AppendElement("Noto Sans Samaritan");
483 break;
484 case Script::TAI_VIET:
485 aFontList.AppendElement("Noto Sans Tai Viet");
486 break;
487 case Script::BAMUM:
488 aFontList.AppendElement("Noto Sans Bamum");
489 break;
490 case Script::LISU:
491 aFontList.AppendElement("Noto Sans Lisu");
492 break;
493 case Script::OLD_SOUTH_ARABIAN:
494 aFontList.AppendElement("Noto Sans Old South Arabian");
495 break;
496 case Script::BASSA_VAH:
497 aFontList.AppendElement("Noto Sans Bassa Vah");
498 break;
499 case Script::DUPLOYAN:
500 aFontList.AppendElement("Noto Sans Duployan");
501 break;
502 case Script::ELBASAN:
503 aFontList.AppendElement("Noto Sans Elbasan");
504 break;
505 case Script::GRANTHA:
506 aFontList.AppendElement("Noto Sans Grantha");
507 break;
508 case Script::MENDE_KIKAKUI:
509 aFontList.AppendElement("Noto Sans Mende Kikakui");
510 break;
511 case Script::MEROITIC_CURSIVE:
512 case Script::MEROITIC_HIEROGLYPHS:
513 aFontList.AppendElement("Noto Sans Meroitic");
514 break;
515 case Script::OLD_NORTH_ARABIAN:
516 aFontList.AppendElement("Noto Sans Old North Arabian");
517 break;
518 case Script::NABATAEAN:
519 aFontList.AppendElement("Noto Sans Nabataean");
520 break;
521 case Script::PALMYRENE:
522 aFontList.AppendElement("Noto Sans Palmyrene");
523 break;
524 case Script::KHUDAWADI:
525 aFontList.AppendElement("Noto Sans Khudawadi");
526 break;
527 case Script::WARANG_CITI:
528 aFontList.AppendElement("Noto Sans Warang Citi");
529 break;
530 case Script::MRO:
531 aFontList.AppendElement("Noto Sans Mro");
532 break;
533 case Script::SHARADA:
534 aFontList.AppendElement("Noto Sans Sharada");
535 break;
536 case Script::SORA_SOMPENG:
537 aFontList.AppendElement("Noto Sans Sora Sompeng");
538 break;
539 case Script::TAKRI:
540 aFontList.AppendElement("Noto Sans Takri");
541 break;
542 case Script::KHOJKI:
543 aFontList.AppendElement("Noto Sans Khojki");
544 break;
545 case Script::TIRHUTA:
546 aFontList.AppendElement("Noto Sans Tirhuta");
547 break;
548 case Script::CAUCASIAN_ALBANIAN:
549 aFontList.AppendElement("Noto Sans Caucasian Albanian");
550 break;
551 case Script::MAHAJANI:
552 aFontList.AppendElement("Noto Sans Mahajani");
553 break;
554 case Script::AHOM:
555 aFontList.AppendElement("Noto Serif Ahom");
556 break;
557 case Script::HATRAN:
558 aFontList.AppendElement("Noto Sans Hatran");
559 break;
560 case Script::MODI:
561 aFontList.AppendElement("Noto Sans Modi");
562 break;
563 case Script::MULTANI:
564 aFontList.AppendElement("Noto Sans Multani");
565 break;
566 case Script::PAU_CIN_HAU:
567 aFontList.AppendElement("Noto Sans Pau Cin Hau");
568 break;
569 case Script::SIDDHAM:
570 aFontList.AppendElement("Noto Sans Siddham");
571 break;
572 case Script::ADLAM:
573 aFontList.AppendElement("Noto Sans Adlam");
574 break;
575 case Script::BHAIKSUKI:
576 aFontList.AppendElement("Noto Sans Bhaiksuki");
577 break;
578 case Script::MARCHEN:
579 aFontList.AppendElement("Noto Sans Marchen");
580 break;
581 case Script::NEWA:
582 aFontList.AppendElement("Noto Sans Newa");
583 break;
584 case Script::OSAGE:
585 aFontList.AppendElement("Noto Sans Osage");
586 break;
587 case Script::HANIFI_ROHINGYA:
588 aFontList.AppendElement("Noto Sans Hanifi Rohingya");
589 break;
590 case Script::WANCHO:
591 aFontList.AppendElement("Noto Sans Wancho");
592 break;
594 // Script codes for which no commonly-installed font is currently known.
595 // Probably future macOS versions will add Noto fonts for many of these,
596 // so we should watch for updates.
597 case Script::OLD_CHURCH_SLAVONIC_CYRILLIC:
598 case Script::DEMOTIC_EGYPTIAN:
599 case Script::HIERATIC_EGYPTIAN:
600 case Script::BLISSYMBOLS:
601 case Script::CIRTH:
602 case Script::KHUTSURI:
603 case Script::HARAPPAN_INDUS:
604 case Script::LATIN_FRAKTUR:
605 case Script::LATIN_GAELIC:
606 case Script::MAYAN_HIEROGLYPHS:
607 case Script::RONGORONGO:
608 case Script::SARATI:
609 case Script::ESTRANGELO_SYRIAC:
610 case Script::WESTERN_SYRIAC:
611 case Script::EASTERN_SYRIAC:
612 case Script::TENGWAR:
613 case Script::VISIBLE_SPEECH:
614 case Script::UNWRITTEN_LANGUAGES:
615 case Script::UNKNOWN:
616 case Script::SIGNWRITING:
617 case Script::MOON:
618 case Script::BOOK_PAHLAVI:
619 case Script::NAKHI_GEBA:
620 case Script::KPELLE:
621 case Script::LOMA:
622 case Script::AFAKA:
623 case Script::JURCHEN:
624 case Script::NUSHU:
625 case Script::TANGUT:
626 case Script::WOLEAI:
627 case Script::ANATOLIAN_HIEROGLYPHS:
628 case Script::MASARAM_GONDI:
629 case Script::SOYOMBO:
630 case Script::ZANABAZAR_SQUARE:
631 case Script::DOGRA:
632 case Script::GUNJALA_GONDI:
633 case Script::MAKASAR:
634 case Script::MEDEFAIDRIN:
635 case Script::SOGDIAN:
636 case Script::OLD_SOGDIAN:
637 case Script::ELYMAIC:
638 case Script::NYIAKENG_PUACHUE_HMONG:
639 case Script::NANDINAGARI:
640 case Script::CHORASMIAN:
641 case Script::DIVES_AKURU:
642 case Script::KHITAN_SMALL_SCRIPT:
643 case Script::YEZIDI:
644 case Script::CYPRO_MINOAN:
645 case Script::OLD_UYGHUR:
646 case Script::TANGSA:
647 case Script::TOTO:
648 case Script::VITHKUQI:
649 case Script::KAWI:
650 case Script::NAG_MUNDARI:
651 break;
654 // Symbols/dingbats are generally Script=COMMON but may be resolved to any
655 // surrounding script run. So we'll always append a couple of likely fonts
656 // for such characters.
657 const uint32_t b = aCh >> 8;
658 if (aRunScript == Script::COMMON || // Stray COMMON chars not resolved
659 (b >= 0x20 && b <= 0x2b) || b == 0x2e || // BMP symbols/punctuation/etc
660 GetGenCategory(aCh) == nsUGenCategory::kSymbol ||
661 GetGenCategory(aCh) == nsUGenCategory::kPunctuation) {
662 if (b == 0x27) {
663 aFontList.AppendElement("Zapf Dingbats");
665 aFontList.AppendElement("Geneva");
666 aFontList.AppendElement("STIXGeneral");
667 aFontList.AppendElement("Apple Symbols");
668 // Japanese fonts also cover a lot of miscellaneous symbols
669 aFontList.AppendElement("Hiragino Sans");
670 aFontList.AppendElement("Hiragino Kaku Gothic ProN");
673 // Arial Unicode MS has lots of glyphs for obscure characters; try it as a
674 // last resort.
675 aFontList.AppendElement("Arial Unicode MS");
678 /*static*/
679 void gfxPlatformMac::LookupSystemFont(
680 mozilla::LookAndFeel::FontID aSystemFontID, nsACString& aSystemFontName,
681 gfxFontStyle& aFontStyle) {
682 gfxMacPlatformFontList* pfl = gfxMacPlatformFontList::PlatformFontList();
683 return pfl->LookupSystemFont(aSystemFontID, aSystemFontName, aFontStyle);
686 uint32_t gfxPlatformMac::ReadAntiAliasingThreshold() {
687 uint32_t threshold = 0; // default == no threshold
689 // first read prefs flag to determine whether to use the setting or not
690 bool useAntiAliasingThreshold =
691 Preferences::GetBool("gfx.use_text_smoothing_setting", false);
693 // if the pref setting is disabled, return 0 which effectively disables this
694 // feature
695 if (!useAntiAliasingThreshold) return threshold;
697 // value set via Appearance pref panel, "Turn off text smoothing for font
698 // sizes xxx and smaller"
699 CFNumberRef prefValue = (CFNumberRef)CFPreferencesCopyAppValue(
700 CFSTR("AppleAntiAliasingThreshold"), kCFPreferencesCurrentApplication);
702 if (prefValue) {
703 if (!CFNumberGetValue(prefValue, kCFNumberIntType, &threshold)) {
704 threshold = 0;
706 CFRelease(prefValue);
709 return threshold;
712 bool gfxPlatformMac::AccelerateLayersByDefault() { return true; }
714 // This is the renderer output callback function, called on the vsync thread
715 static CVReturn VsyncCallback(CVDisplayLinkRef aDisplayLink,
716 const CVTimeStamp* aNow,
717 const CVTimeStamp* aOutputTime,
718 CVOptionFlags aFlagsIn, CVOptionFlags* aFlagsOut,
719 void* aDisplayLinkContext);
721 class OSXVsyncSource final : public VsyncSource {
722 public:
723 OSXVsyncSource()
724 : mDisplayLink(nullptr, "OSXVsyncSource::OSXDisplay::mDisplayLink") {
725 MOZ_ASSERT(NS_IsMainThread());
726 mTimer = NS_NewTimer();
727 CGDisplayRegisterReconfigurationCallback(DisplayReconfigurationCallback,
728 this);
731 virtual ~OSXVsyncSource() {
732 MOZ_ASSERT(NS_IsMainThread());
733 CGDisplayRemoveReconfigurationCallback(DisplayReconfigurationCallback,
734 this);
737 static void RetryEnableVsync(nsITimer* aTimer, void* aOsxVsyncSource) {
738 MOZ_ASSERT(NS_IsMainThread());
739 OSXVsyncSource* osxVsyncSource =
740 static_cast<OSXVsyncSource*>(aOsxVsyncSource);
741 MOZ_ASSERT(osxVsyncSource);
742 osxVsyncSource->EnableVsync();
745 void EnableVsync() override {
746 MOZ_ASSERT(NS_IsMainThread());
747 if (IsVsyncEnabled()) {
748 return;
751 auto displayLink = mDisplayLink.Lock();
753 // Create a display link capable of being used with all active displays
754 // TODO: See if we need to create an active DisplayLink for each monitor
755 // in multi-monitor situations. According to the docs, it is compatible
756 // with all displays running on the computer But if we have different
757 // monitors at different display rates, we may hit issues.
758 CVReturn retval = CVDisplayLinkCreateWithActiveCGDisplays(&*displayLink);
760 // Workaround for bug 1201401: CVDisplayLinkCreateWithCGDisplays()
761 // (called by CVDisplayLinkCreateWithActiveCGDisplays()) sometimes
762 // creates a CVDisplayLinkRef with an uninitialized (nulled) internal
763 // pointer. If we continue to use this CVDisplayLinkRef, we will
764 // eventually crash in CVCGDisplayLink::getDisplayTimes(), where the
765 // internal pointer is dereferenced. Fortunately, when this happens
766 // another internal variable is also left uninitialized (zeroed),
767 // which is accessible via CVDisplayLinkGetCurrentCGDisplay(). In
768 // normal conditions the current display is never zero.
769 if ((retval == kCVReturnSuccess) &&
770 (CVDisplayLinkGetCurrentCGDisplay(*displayLink) == 0)) {
771 retval = kCVReturnInvalidDisplay;
774 if (retval != kCVReturnSuccess) {
775 NS_WARNING(
776 "Could not create a display link with all active displays. "
777 "Retrying");
778 CVDisplayLinkRelease(*displayLink);
779 *displayLink = nullptr;
781 // bug 1142708 - When coming back from sleep,
782 // or when changing displays, active displays may not be ready yet,
783 // even if listening for the kIOMessageSystemHasPoweredOn event
784 // from OS X sleep notifications.
785 // Active displays are those that are drawable.
786 // bug 1144638 - When changing display configurations and getting
787 // notifications from CGDisplayReconfigurationCallBack, the
788 // callback gets called twice for each active display
789 // so it's difficult to know when all displays are active.
790 // Instead, try again soon. The delay is arbitrary. 100ms chosen
791 // because on a late 2013 15" retina, it takes about that
792 // long to come back up from sleep.
793 uint32_t delay = 100;
794 mTimer->InitWithNamedFuncCallback(RetryEnableVsync, this, delay,
795 nsITimer::TYPE_ONE_SHOT,
796 "RetryEnableVsync");
797 return;
800 if (CVDisplayLinkSetOutputCallback(*displayLink, &VsyncCallback, this) !=
801 kCVReturnSuccess) {
802 NS_WARNING("Could not set displaylink output callback");
803 CVDisplayLinkRelease(*displayLink);
804 *displayLink = nullptr;
805 return;
808 mPreviousTimestamp = TimeStamp::Now();
809 if (CVDisplayLinkStart(*displayLink) != kCVReturnSuccess) {
810 NS_WARNING("Could not activate the display link");
811 CVDisplayLinkRelease(*displayLink);
812 *displayLink = nullptr;
815 CVTime vsyncRate =
816 CVDisplayLinkGetNominalOutputVideoRefreshPeriod(*displayLink);
817 if (vsyncRate.flags & kCVTimeIsIndefinite) {
818 NS_WARNING("Could not get vsync rate, setting to 60.");
819 mVsyncRate = TimeDuration::FromMilliseconds(1000.0 / 60.0);
820 } else {
821 int64_t timeValue = vsyncRate.timeValue;
822 int64_t timeScale = vsyncRate.timeScale;
823 const int milliseconds = 1000;
824 float rateInMs = ((double)timeValue / (double)timeScale) * milliseconds;
825 mVsyncRate = TimeDuration::FromMilliseconds(rateInMs);
829 void DisableVsync() override {
830 MOZ_ASSERT(NS_IsMainThread());
831 if (!IsVsyncEnabled()) {
832 return;
835 // Release the display link
836 auto displayLink = mDisplayLink.Lock();
837 if (*displayLink) {
838 CVDisplayLinkRelease(*displayLink);
839 *displayLink = nullptr;
843 bool IsVsyncEnabled() override {
844 MOZ_ASSERT(NS_IsMainThread());
845 auto displayLink = mDisplayLink.Lock();
846 return *displayLink != nullptr;
849 TimeDuration GetVsyncRate() override { return mVsyncRate; }
851 void Shutdown() override {
852 MOZ_ASSERT(NS_IsMainThread());
853 mTimer->Cancel();
854 mTimer = nullptr;
855 DisableVsync();
858 // The vsync timestamps given by the CVDisplayLinkCallback are
859 // in the future for the NEXT frame. Large parts of Gecko, such
860 // as animations assume a timestamp at either now or in the past.
861 // Normalize the timestamps given to the VsyncDispatchers to the vsync
862 // that just occured, not the vsync that is upcoming.
863 TimeStamp mPreviousTimestamp;
865 private:
866 static void DisplayReconfigurationCallback(CGDirectDisplayID aDisplay,
867 CGDisplayChangeSummaryFlags aFlags,
868 void* aUserInfo) {
869 static_cast<OSXVsyncSource*>(aUserInfo)->OnDisplayReconfiguration(aDisplay,
870 aFlags);
873 void OnDisplayReconfiguration(CGDirectDisplayID aDisplay,
874 CGDisplayChangeSummaryFlags aFlags) {
875 // Display reconfiguration notifications are fired in two phases: Before
876 // the reconfiguration and after the reconfiguration.
877 // All displays are notified before (with a "BeginConfiguration" flag),
878 // and the reconfigured displays are notified again after the
879 // configuration.
880 if (aFlags & kCGDisplayBeginConfigurationFlag) {
881 // We're only interested in the "after" notification, for the display
882 // link's current display.
883 return;
886 if (!NS_IsMainThread()) {
887 return;
890 bool didReconfigureCurrentDisplayLinkDisplay = false;
891 { // scope for lock
892 auto displayLink = mDisplayLink.Lock();
893 didReconfigureCurrentDisplayLinkDisplay =
894 *displayLink &&
895 CVDisplayLinkGetCurrentCGDisplay(*displayLink) == aDisplay;
898 if (didReconfigureCurrentDisplayLinkDisplay) {
899 // The link's current display has been reconfigured.
900 // Recreate the display link, because otherwise it may be stuck with a
901 // "removed" display forever and never notify us again.
902 DisableVsync();
903 EnableVsync();
907 // Accessed from main thread and from display reconfiguration callback
908 // thread... which also happens to be the main thread.
909 DataMutex<CVDisplayLinkRef> mDisplayLink;
911 // Accessed only from the main thread.
912 RefPtr<nsITimer> mTimer;
913 TimeDuration mVsyncRate;
914 }; // OSXVsyncSource
916 static CVReturn VsyncCallback(CVDisplayLinkRef aDisplayLink,
917 const CVTimeStamp* aNow,
918 const CVTimeStamp* aOutputTime,
919 CVOptionFlags aFlagsIn, CVOptionFlags* aFlagsOut,
920 void* aDisplayLinkContext) {
921 // Executed on OS X hardware vsync thread
922 OSXVsyncSource* vsyncSource = (OSXVsyncSource*)aDisplayLinkContext;
924 mozilla::TimeStamp outputTime =
925 mozilla::TimeStamp::FromSystemTime(aOutputTime->hostTime);
926 mozilla::TimeStamp nextVsync = outputTime;
927 mozilla::TimeStamp previousVsync = vsyncSource->mPreviousTimestamp;
928 mozilla::TimeStamp now = TimeStamp::Now();
930 // Snow leopard sometimes sends vsync timestamps very far in the past.
931 // Normalize the vsync timestamps to now.
932 if (nextVsync <= previousVsync) {
933 nextVsync = now;
934 previousVsync = now;
935 } else if (now < previousVsync) {
936 // Bug 1158321 - The VsyncCallback can sometimes execute before the reported
937 // vsync time. In those cases, normalize the timestamp to Now() as sending
938 // timestamps in the future has undefined behavior. See the comment above
939 // OSXVsyncSource::mPreviousTimestamp
940 previousVsync = now;
943 vsyncSource->mPreviousTimestamp = nextVsync;
945 vsyncSource->NotifyVsync(previousVsync, outputTime);
946 return kCVReturnSuccess;
949 already_AddRefed<mozilla::gfx::VsyncSource>
950 gfxPlatformMac::CreateGlobalHardwareVsyncSource() {
951 RefPtr<VsyncSource> osxVsyncSource = new OSXVsyncSource();
952 osxVsyncSource->EnableVsync();
953 if (!osxVsyncSource->IsVsyncEnabled()) {
954 NS_WARNING(
955 "OS X Vsync source not enabled. Falling back to software vsync.");
956 return GetSoftwareVsyncSource();
959 osxVsyncSource->DisableVsync();
960 return osxVsyncSource.forget();
963 bool gfxPlatformMac::SupportsHDR() {
964 // HDR has 3 requirements:
965 // 1) high peak brightness
966 // 2) high contrast ratio
967 // 3) color depth > 24
968 if (GetScreenDepth() <= 24) {
969 return false;
971 // Screen is capable. Is the OS capable?
972 #ifdef EARLY_BETA_OR_EARLIER
973 // More-or-less supported in Catalina.
974 return nsCocoaFeatures::OnCatalinaOrLater();
975 #else
976 // Definitely supported in Big Sur.
977 return nsCocoaFeatures::OnBigSurOrLater();
978 #endif
981 nsTArray<uint8_t> gfxPlatformMac::GetPlatformCMSOutputProfileData() {
982 nsTArray<uint8_t> prefProfileData = GetPrefCMSOutputProfileData();
983 if (!prefProfileData.IsEmpty()) {
984 return prefProfileData;
987 CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID());
988 if (!cspace) {
989 cspace = ::CGColorSpaceCreateDeviceRGB();
991 if (!cspace) {
992 return nsTArray<uint8_t>();
995 CFDataRef iccp = ::CGColorSpaceCopyICCProfile(cspace);
997 ::CFRelease(cspace);
999 if (!iccp) {
1000 return nsTArray<uint8_t>();
1003 // copy to external buffer
1004 size_t size = static_cast<size_t>(::CFDataGetLength(iccp));
1006 nsTArray<uint8_t> result;
1008 if (size > 0) {
1009 result.AppendElements(::CFDataGetBytePtr(iccp), size);
1012 ::CFRelease(iccp);
1014 return result;
1017 bool gfxPlatformMac::CheckVariationFontSupport() {
1018 // We don't allow variation fonts to be enabled before 10.13,
1019 // as although the Core Text APIs existed, they are known to be
1020 // fairly buggy.
1021 // (Note that Safari also requires 10.13 for variation-font support.)
1022 return nsCocoaFeatures::OnHighSierraOrLater();
1025 void gfxPlatformMac::InitPlatformGPUProcessPrefs() {
1026 FeatureState& gpuProc = gfxConfig::GetFeature(Feature::GPU_PROCESS);
1027 gpuProc.ForceDisable(FeatureStatus::Blocked,
1028 "GPU process does not work on Mac",
1029 "FEATURE_FAILURE_MAC_GPU_PROC"_ns);