Changeset 244372 in webkit


Ignore:
Timestamp:
Apr 16, 2019 11:16:04 PM (5 years ago)
Author:
zandobersek@gmail.com
Message:

ScalableImageDecoder: don't forcefully decode image data when querying frame completeness, duration
https://bugs.webkit.org/show_bug.cgi?id=191354
<rdar://problem/46123406>

Reviewed by Michael Catanzaro.

ScalableImageDecoder::frameIsCompleteAtIndex() should only check the
index validity and, if the index is valid, check for completeness of the
corresponding frame. ScalableImageDecoder::frameDurationAtIndex() should
also only retrieve duration for already-complete frames, or expand the
default 0-second value according to the flashing-protection rule when
the target frame is not yet complete.

Both methods avoid calling ScalableImageDecoder::frameBufferAtIndex()
as that method goes on and decodes image data to determine specific
information. The ImageSource class that's querying this information
doesn't anticipate this, and doesn't handle the increased memory
consumption of the decoded data, leaving MemoryCache in the blind about
the image resource's actual amount of consumed memory. ImageSource can
instead gracefully handle any incomplete frame by marking the decoding
status for this frame as only partial.

  • platform/image-decoders/ScalableImageDecoder.cpp:

(WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const):
(WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const):
(WebCore::ScalableImageDecoder::frameDurationAtIndex const):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r244369 r244372  
     12019-04-16  Zan Dobersek  <zdobersek@igalia.com>
     2
     3        ScalableImageDecoder: don't forcefully decode image data when querying frame completeness, duration
     4        https://bugs.webkit.org/show_bug.cgi?id=191354
     5        <rdar://problem/46123406>
     6
     7        Reviewed by Michael Catanzaro.
     8
     9        ScalableImageDecoder::frameIsCompleteAtIndex() should only check the
     10        index validity and, if the index is valid, check for completeness of the
     11        corresponding frame. ScalableImageDecoder::frameDurationAtIndex() should
     12        also only retrieve duration for already-complete frames, or expand the
     13        default 0-second value according to the flashing-protection rule when
     14        the target frame is not yet complete.
     15
     16        Both methods avoid calling ScalableImageDecoder::frameBufferAtIndex()
     17        as that method goes on and decodes image data to determine specific
     18        information. The ImageSource class that's querying this information
     19        doesn't anticipate this, and doesn't handle the increased memory
     20        consumption of the decoded data, leaving MemoryCache in the blind about
     21        the image resource's actual amount of consumed memory. ImageSource can
     22        instead gracefully handle any incomplete frame by marking the decoding
     23        status for this frame as only partial.
     24
     25        * platform/image-decoders/ScalableImageDecoder.cpp:
     26        (WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const):
     27        (WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const):
     28        (WebCore::ScalableImageDecoder::frameDurationAtIndex const):
     29
    1302019-04-16  Ross Kirsling  <ross.kirsling@sony.com>
    231
  • trunk/Source/WebCore/platform/image-decoders/ScalableImageDecoder.cpp

    r240428 r244372  
    197197{
    198198    LockHolder lockHolder(m_mutex);
    199     // FIXME(176089): asking whether enough data has been appended for a decode
    200     // operation to succeed should not require decoding the entire frame.
    201     // This function should be implementable in a way that allows const.
    202     auto* buffer = const_cast<ScalableImageDecoder*>(this)->frameBufferAtIndex(index);
    203     return buffer && buffer->isComplete();
     199    if (index >= m_frameBufferCache.size())
     200        return false;
     201
     202    auto& frame = m_frameBufferCache[index];
     203    return frame.isComplete();
    204204}
    205205
     
    209209    if (m_frameBufferCache.size() <= index)
    210210        return true;
    211     if (m_frameBufferCache[index].isComplete())
    212         return m_frameBufferCache[index].hasAlpha();
    213     return true;
     211
     212    auto& frame = m_frameBufferCache[index];
     213    if (!frame.isComplete())
     214        return true;
     215    return frame.hasAlpha();
    214216}
    215217
     
    226228{
    227229    LockHolder lockHolder(m_mutex);
    228     // FIXME(176089): asking for the duration of a sub-image should not require decoding
    229     // the entire frame. This function should be implementable in a way that
    230     // allows const.
    231     auto* buffer = const_cast<ScalableImageDecoder*>(this)->frameBufferAtIndex(index);
    232     if (!buffer || buffer->isInvalid())
     230    if (index >= m_frameBufferCache.size())
    233231        return 0_s;
    234    
     232
     233    // Returning 0_s in case of an incomplete frame can break display of animated image formats.
     234    // We pick up the decoded duration if it's available, otherwise the default 0_s value is
     235    // adjusted below.
     236    Seconds duration = 0_s;
     237    auto& frame = m_frameBufferCache[index];
     238    if (frame.isComplete())
     239        duration = frame.duration();
     240
    235241    // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
    236242    // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
    237243    // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>
    238244    // for more information.
    239     if (buffer->duration() < 11_ms)
     245    if (duration < 11_ms)
    240246        return 100_ms;
    241     return buffer->duration();
     247    return duration;
    242248}
    243249
Note: See TracChangeset for help on using the changeset viewer.