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