⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 281186 in webkit


Ignore:
Timestamp:
Aug 18, 2021, 6:42:48 AM (5 years ago)
Author:
Wenson Hsieh
Message:

REGRESSION (iOS 15): DoubleDown Casino app won't load past launch page
​https://bugs.webkit.org/show_bug.cgi?id=229200
rdar://81636256

Reviewed by Myles C. Maxfield.

The changes in ​https://webkit.org/b/228216 to fix rdar://80473805 introduced a mechanism to keep track of uses
of cached fonts and images in display list items in the web and GPU processes, via a useCount counter variable
that's incremented in the web process whenever the font or image is used in a display list item and decremented
in the GPU process whenever the item is processed.

However, the code to increment useCount in the web process currently only triggers at most once per rendering
update — this means that if there are multiple canvas drawing commands that use fonts in the same rendering
update, the web process' notion of useCount will fall out of sync with the GPU process' notion of useCount.

In most cases, this causes the cached font to remain for longer in the GPU process than necessary; however, in
this specific scenario, it's possible for the web process to tell the GPU process to release the cached font too
early, which causes the GPU process to prematurely purge the font from the cache, and subsequently wait for the
cached font to arrive (which will never arrive, since the web process has already released the font).

In other words, the timeline of events between the web and GPU processes looks like this (where f is a cached
web font, A_f is a drawing command that uses f, and B_f is another drawing command that uses f).

WEB GPU
==============================================================

  1. Cache f
  2. Append A_f
    1. Cache f
    2. Play back A_f
  3. Append B_f
  4. Release f (use count was 1 here)
    1. Release f (use count dropped from 1 to 0)
    2. Play back B_f ...and then display list playback stops due to f not being in the cache.

To address this, we simply move the useCount increment in the web process out of the rendering update check.
The original intent of the fix for bug #228216 was to allow for useCount to increment as many times as needed
per rendering update, so this limitation was unintentional.

Unfortunately, I have not been able to come up with a layout test that reliably reproduces this scenario (yet).

  • WebProcess/GPU/graphics/RemoteResourceCacheProxy.cpp:

(WebKit::RemoteResourceCacheProxy::recordFontUse):

Location:
trunk/Source/WebKit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r281175 r281186  
     12021-08-18  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        REGRESSION (iOS 15): DoubleDown Casino app won't load past launch page
     4        https://bugs.webkit.org/show_bug.cgi?id=229200
     5        rdar://81636256
     6
     7        Reviewed by Myles C. Maxfield.
     8
     9        The changes in https://webkit.org/b/228216 to fix rdar://80473805 introduced a mechanism to keep track of uses
     10        of cached fonts and images in display list items in the web and GPU processes, via a `useCount` counter variable
     11        that's incremented in the web process whenever the font or image is used in a display list item and decremented
     12        in the GPU process whenever the item is processed.
     13
     14        However, the code to increment `useCount` in the web process currently only triggers at most once per rendering
     15        update — this means that if there are multiple canvas drawing commands that use fonts in the same rendering
     16        update, the web process' notion of `useCount` will fall out of sync with the GPU process' notion of `useCount`.
     17
     18        In most cases, this causes the cached font to remain for longer in the GPU process than necessary; however, in
     19        this specific scenario, it's possible for the web process to tell the GPU process to release the cached font too
     20        early, which causes the GPU process to prematurely purge the font from the cache, and subsequently wait for the
     21        cached font to arrive (which will never arrive, since the web process has already released the font).
     22
     23        In other words, the timeline of events between the web and GPU processes looks like this (where `f` is a cached
     24        web font, `A_f` is a drawing command that uses `f`, and `B_f` is another drawing command that uses `f`).
     25
     26        WEB                                             GPU
     27        ==============================================================
     28        1. Cache `f`
     29        2. Append `A_f`
     30                                                        3. Cache `f`
     31                                                        4. Play back `A_f`
     32        5. Append `B_f`
     33        6. Release `f` (use count was 1 here)
     34                                                        7. Release `f` (use count dropped from 1 to 0)
     35                                                        8. Play back `B_f`
     36                                                        ...and then display list playback stops due to `f` not being in
     37                                                        the cache.
     38
     39        To address this, we simply move the `useCount` increment in the web process out of the rendering update check.
     40        The original intent of the fix for bug #228216 was to allow for `useCount` to increment as many times as needed
     41        per rendering update, so this limitation was unintentional.
     42
     43        Unfortunately, I have not been able to come up with a layout test that reliably reproduces this scenario (yet).
     44
     45        * WebProcess/GPU/graphics/RemoteResourceCacheProxy.cpp:
     46        (WebKit::RemoteResourceCacheProxy::recordFontUse):
     47
    1482021-08-17  Sihui Liu  <sihui_liu@apple.com>
    249
  • trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteResourceCacheProxy.cpp

    r280981 r281186  
    133133
    134134    auto& currentState = result.iterator->value;
     135    ++currentState.useCount;
    135136    if (currentState.lastRenderingUpdateVersionUsedWithin != m_remoteRenderingBackendProxy.renderingUpdateID()) {
    136137        currentState.lastRenderingUpdateVersionUsedWithin = m_remoteRenderingBackendProxy.renderingUpdateID();
    137         ++currentState.useCount;
    138138        ++m_numberOfFontsUsedInCurrentRenderingUpdate;
    139139    }
Note: See TracChangeset for help on using the changeset viewer.