Bug 215688

Summary: [Cocoa] Prepare for migrating to CTFontHasTable() once it's faster than CTFontCopyAvailableTables()
Product: WebKit Reporter: Myles C. Maxfield <mmaxfield>
Component: New BugsAssignee: Myles C. Maxfield <mmaxfield>
Status: RESOLVED FIXED    
Severity: Normal CC: benjamin, cdumez, cmarcelo, darin, ews-watchlist, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on:    
Bug Blocks: 230248    
Attachments:
Description Flags
Patch
none
Patch
darin: review+
Patch for committing
none
Patch for committing
none
Patch for committing
none
Patch for committing
none
Patch for committing
none
Patch for committing
none
Patch for committing
none
Patch for committing
none
Patch for committing
none
Patch for committing none

Description Myles C. Maxfield 2020-08-19 22:14:38 PDT
[Cocoa] CTFontHasTable() is faster than iterating over every table in the font
Comment 1 Myles C. Maxfield 2020-08-19 22:16:46 PDT
Created attachment 406917 [details]
Patch
Comment 2 Myles C. Maxfield 2020-08-19 22:17:09 PDT
<rdar://problem/57131142>
Comment 3 Myles C. Maxfield 2020-09-05 01:56:40 PDT
Created attachment 408077 [details]
Patch
Comment 4 Darin Adler 2020-09-05 08:51:18 PDT
Comment on attachment 408077 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=408077&action=review

> Source/WTF/wtf/PlatformUse.h:309
> +#define USE_CTFONTHASTABLE 1

Is this really a USE and not a HAVE?

USE for policy. HAVE for capability. I assume we’d use this whenever we have a working implementation.

> Source/WebCore/platform/graphics/cocoa/FontCocoa.mm:65
>  static bool fontHasVerticalGlyphs(CTFontRef ctFont)

Seems like the argument can just be named font.

> Source/WebCore/platform/graphics/cocoa/FontCocoa.mm:71
>      RetainPtr<CFArrayRef> tableTags = adoptCF(CTFontCopyAvailableTables(ctFont, kCTFontTableOptionNoOptions));

auto

> Source/WebCore/platform/graphics/cocoa/FontCocoa.mm:76
> +        CTFontTableTag tag = static_cast<CTFontTableTag>(reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(tableTags.get(), index)));

auto

Is the static_cast really needed? I would think that conversion between integer types would work without it. In fact we could even compare uintptr_t values with CTFontTableTag constants without having to make the types match. I think using auto and taking out the static_cast would be good.

> Source/WebCore/platform/graphics/opentype/OpenTypeCG.cpp:42
>  bool fontHasMathTable(CTFontRef ctFont)

Could this share code with the other some day?

A function that takes a CTFontRef and an argument list of tables and checks for any of them? Would be nice to not have this twice.

> Source/WebCore/platform/graphics/opentype/OpenTypeCG.cpp:47
>      RetainPtr<CFArrayRef> tableTags = adoptCF(CTFontCopyAvailableTables(ctFont, kCTFontTableOptionNoOptions));

Ditto.

> Source/WebCore/platform/graphics/opentype/OpenTypeCG.cpp:52
> +        CTFontTableTag tag = static_cast<CTFontTableTag>(reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(tableTags.get(), index)));

Ditto.
Comment 5 Myles C. Maxfield 2020-09-05 11:11:41 PDT
Created attachment 408089 [details]
Patch for committing
Comment 6 Myles C. Maxfield 2020-09-05 11:30:37 PDT
Created attachment 408090 [details]
Patch for committing
Comment 7 Myles C. Maxfield 2020-09-05 11:35:01 PDT
Created attachment 408091 [details]
Patch for committing
Comment 8 Myles C. Maxfield 2020-09-05 14:28:29 PDT
Created attachment 408096 [details]
Patch for committing
Comment 9 Myles C. Maxfield 2020-09-05 14:48:09 PDT
Created attachment 408100 [details]
Patch for committing
Comment 10 Myles C. Maxfield 2020-09-06 15:39:39 PDT
Created attachment 408145 [details]
Patch for committing
Comment 11 Myles C. Maxfield 2020-09-06 15:46:20 PDT
Created attachment 408146 [details]
Patch for committing
Comment 12 Darin Adler 2020-09-06 16:02:06 PDT
Comment on attachment 408146 [details]
Patch for committing

View in context: https://bugs.webkit.org/attachment.cgi?id=408146&action=review

> Source/WebCore/platform/graphics/Font.cpp:488
> +#if USE(CG)
> +bool fontHasTable(CTFontRef ctFont, unsigned tableTag)

In the past sometimes we have literally named our function "CTFontHasTable" and just compile it when on a system that doesn’t have it. Risky though.

> Source/WebCore/platform/graphics/Font.cpp:498
> +        auto tag = static_cast<CTFontTableTag>(reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(tableTags.get(), index)));

I don’t think the static_cast to CTFontTableTag here is needed.

> Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:495
> +        bool foundFvar = CTFontHasTable(font, kCTFontTableFvar);
> +        foundStat = CTFontHasTable(font, kCTFontTableSTAT);
> +        aatShaping = CTFontHasTable(font, kCTFontTableMorx) || CTFontHasTable(font, kCTFontTableMort);
> +        openTypeShaping = CTFontHasTable(font, kCTFontTableGPOS) || CTFontHasTable(font, kCTFontTableGSUB);
> +        foundTrak = CTFontHasTable(font, kCTFontTableTrak);

Are you sure that 7 calls to this function are fast enough?

> Source/WebCore/platform/graphics/cocoa/FontCocoa.mm:67
> +    return fontHasTable(font, kCTFontTableVhea) || fontHasTable(font, kCTFontTableVORG);

Is it OK that this now is twice as slow on older systems?
Comment 13 Myles C. Maxfield 2020-09-06 17:25:18 PDT
Created attachment 408154 [details]
Patch for committing
Comment 14 Myles C. Maxfield 2020-09-06 17:27:22 PDT
Comment on attachment 408146 [details]
Patch for committing

View in context: https://bugs.webkit.org/attachment.cgi?id=408146&action=review

>> Source/WebCore/platform/graphics/Font.cpp:498
>> +        auto tag = static_cast<CTFontTableTag>(reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(tableTags.get(), index)));
> 
> I don’t think the static_cast to CTFontTableTag here is needed.

See the obsoleted patches in this bug. I tried taking it out but the builds turned red.
Comment 15 Myles C. Maxfield 2020-09-06 17:31:56 PDT
Comment on attachment 408146 [details]
Patch for committing

View in context: https://bugs.webkit.org/attachment.cgi?id=408146&action=review

>> Source/WebCore/platform/graphics/cocoa/FontCocoa.mm:67
>> +    return fontHasTable(font, kCTFontTableVhea) || fontHasTable(font, kCTFontTableVORG);
> 
> Is it OK that this now is twice as slow on older systems?

I don't have a benchmark (yet), but the idea is that asking a font if it has a particular table is O(1) instead of O(n) to iterate through all tables. Also, there doesn't have to be a CFArray allocation.

I can make a tiny microbenchmark to verify this intuition.
Comment 16 Myles C. Maxfield 2020-09-06 18:01:21 PDT
Heyyyyy guess what? From creating a microbenchmark, it turns out CTFontHasTable() is slower than the loop! I've filed <rdar://problem/68438759>

I'll modify this patch to always run the loop, but I'll keep the design where this stuff is centralized so that when that radar is fixed we can have a drop-in replacement. I guess I can make a second variation of the loop which looks for two tag names, also.
Comment 17 Myles C. Maxfield 2020-09-06 18:17:56 PDT
Created attachment 408158 [details]
Patch for committing
Comment 18 Myles C. Maxfield 2020-09-06 18:20:15 PDT
Created attachment 408159 [details]
Patch for committing
Comment 19 EWS 2020-09-06 23:11:12 PDT
Committed r266692: <https://trac.webkit.org/changeset/266692>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 408159 [details].