Bug 215688 - [Cocoa] Prepare for migrating to CTFontHasTable() once it's faster than CTFontCopyAvailableTables()
Summary: [Cocoa] Prepare for migrating to CTFontHasTable() once it's faster than CTFon...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Myles C. Maxfield
URL:
Keywords: InRadar
Depends on:
Blocks: 230248
  Show dependency treegraph
 
Reported: 2020-08-19 22:14 PDT by Myles C. Maxfield
Modified: 2021-09-14 11:43 PDT (History)
6 users (show)

See Also:


Attachments
Patch (9.12 KB, patch)
2020-08-19 22:16 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch (9.24 KB, patch)
2020-09-05 01:56 PDT, Myles C. Maxfield
darin: review+
Details | Formatted Diff | Diff
Patch for committing (10.28 KB, patch)
2020-09-05 11:11 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch for committing (10.29 KB, patch)
2020-09-05 11:30 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch for committing (10.51 KB, patch)
2020-09-05 11:35 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch for committing (10.56 KB, patch)
2020-09-05 14:28 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch for committing (10.85 KB, patch)
2020-09-05 14:48 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch for committing (11.16 KB, patch)
2020-09-06 15:39 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch for committing (11.16 KB, patch)
2020-09-06 15:46 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch for committing (12.03 KB, patch)
2020-09-06 17:25 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch for committing (12.25 KB, patch)
2020-09-06 18:17 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch for committing (9.89 KB, patch)
2020-09-06 18:20 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
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].