Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-71737

Font family fallback cache results in startup lag on Windows

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • None
    • 5.9.7, 5.11.2
    • GUI: Font handling
    • None
    • Windows 10
      Version 10.0.17134 Build 17134
    • Windows
    • a332f3fabc29f796526202648eddf35a24f1cb67 (qt/qtbase/dev) 1a991e186256b137d911ddca41aa506016b0e349 (qt/qtbase/5.15)

    Description

      When switching from Qt 4.8.7 to Qt 5.9.7 we noticed a visible lag in application startup on Windows 10. Depending on the number of fonts installed, the lag was between about 500ms and one second even on fast workstations.

      We could narrow the issue down to the family fallback cache created by QPlatformFontDatabase::fallbacksForFamily which results in a list of about 500 to 1000 fallbacks per font family. Creating this large list of fallback fonts the first time takes a significant amount of time.

      The problem can be reproduced using the test program: main.cpp. In the first paintEvent the font family fallback cache list is created. This causes a visible delay between showing the blank button and the text of the button on Windows 10.

      When running the test program compiled against Qt 4.8.7 on the same machine, the first paint Event only takes 20ms. No lag is visible between creating the button and showing its text.

      The attached patch reduces the fallback families to ten preferred fallbacks. After applying it, the startup performance is on par with Qt 4.8.7.

      Qt applications like Linguist and Designer start noticeable faster as well with the patch applied.

      A proper fix probably probably has to be done differently to account for more than ten fallbacks for less common glyphs that are not available in the first ten preferred fallbacks fonts. I don't know how likely this is. I noticed there is a already a cap of 256 fallbacks used in QFontEngineMultie::glypIndex and QFontEngineMulti::stringToCMap.

      edit: I reproduced a problem with Japanese glyphs for the font Courier when only ten fallbacks are used. See the test program: mainWithFailingJapaneseCharacters.cpp.

      A possible solution to this would be to not create the fallback list beforehand, but find the next fallback on demand until the first working fallback for the given glyph is found in QFontEngineMulti.

      Attachments

        1. startuplag.pro
          0.1 kB
        2. qtbug71737.zip
          2 kB
        3. qtbug71737_diag.diff
          0.5 kB
        4. qt-5.9.6-slow-font-fallback-cache.patch
          1.0 kB
        5. mainWithFailingJapaneseCharacters.cpp
          2 kB
        6. main.cpp
          2 kB
        7. image-2018-12-05-17-52-19-388.png
          image-2018-12-05-17-52-19-388.png
          67 kB

        Issue Links

          For Gerrit Dashboard: QTBUG-71737
          # Subject Branch Project Status CR V

          Activity

            People

              esabraha Eskil Abrahamsen Blomfeldt
              midoppler Michael Doppler
              Votes:
              2 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes