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

Changeset 292290 in webkit


Ignore:
Timestamp:
Apr 4, 2022, 8:55:35 AM (4 years ago)
Author:
jer.noble@apple.com
Message:

[Perf] HTMLVideoElement is performing synchronous paints; causing main thread hangs
https://bugs.webkit.org/show_bug.cgi?id=238707
<rdar://91025299>

Reviewed by Eric Carlson.

Spin trace diagnostics show that the main thread of the WebContent process is often hung,
blocked on a synchronous Paint message to the GPU process; in turn, the GPU process is often
busy performing media-related work, but in each of the cases found, painting is unnecessary.
The media player in question is accelerated, and should only be painted during layer snapshotting
or during a print operation.

Only paint if the renderer is not accelerated, the media element is not accelerated, or if
the paint operation isn't flattening or snapshotting. HTMLMediaElement inappropriately caches
the value of MediaPlayer::supportsAcceleratedRendering(), under the (incorrect) assumption that
the value cannot change during the lifetime of the MediaPlayer, so remove this caching layer.

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::mediaEngineWasUpdated):
(WebCore::HTMLMediaElement::clearMediaPlayer):

  • html/HTMLMediaElement.h:

(WebCore::HTMLMediaElement::supportsAcceleratedRendering const):

  • rendering/RenderVideo.cpp:

(WebCore::RenderVideo::paintReplaced):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r292279 r292290  
     12022-04-04  Jer Noble  <jer.noble@apple.com>
     2
     3        [Perf] HTMLVideoElement is performing synchronous paints; causing main thread hangs
     4        https://bugs.webkit.org/show_bug.cgi?id=238707
     5        <rdar://91025299>
     6
     7        Reviewed by Eric Carlson.
     8
     9        Spin trace diagnostics show that the main thread of the WebContent process is often hung,
     10        blocked on a synchronous Paint message to the GPU process; in turn, the GPU process is often
     11        busy performing media-related work, but in each of the cases found, painting is unnecessary.
     12        The media player in question is accelerated, and should only be painted during layer snapshotting
     13        or during a print operation.
     14
     15        Only paint if the renderer is not accelerated, the media element is not accelerated, or if
     16        the paint operation isn't flattening or snapshotting. HTMLMediaElement inappropriately caches
     17        the value of MediaPlayer::supportsAcceleratedRendering(), under the (incorrect) assumption that
     18        the value cannot change during the lifetime of the MediaPlayer, so remove this caching layer.
     19
     20        * html/HTMLMediaElement.cpp:
     21        (WebCore::HTMLMediaElement::mediaEngineWasUpdated):
     22        (WebCore::HTMLMediaElement::clearMediaPlayer):
     23        * html/HTMLMediaElement.h:
     24        (WebCore::HTMLMediaElement::supportsAcceleratedRendering const):
     25        * rendering/RenderVideo.cpp:
     26        (WebCore::RenderVideo::paintReplaced):
     27
    1282022-03-28  Antoine Quint  <graouts@webkit.org>
    229
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r292252 r292290  
    53415341
    53425342    beginProcessingMediaPlayerCallback();
    5343     m_cachedSupportsAcceleratedRendering = m_player && m_player->supportsAcceleratedRendering();
    53445343    updateRenderer();
    53455344    endProcessingMediaPlayerCallback();
     
    59005899        m_player->invalidate();
    59015900        m_player = nullptr;
    5902         m_cachedSupportsAcceleratedRendering = false;
    59035901    }
    59045902    schedulePlaybackControlsManagerUpdate();
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r292252 r292290  
    158158    WEBCORE_EXPORT std::optional<MediaPlayerIdentifier> playerIdentifier() const;
    159159
    160     bool supportsAcceleratedRendering() const { return m_cachedSupportsAcceleratedRendering; }
     160    bool supportsAcceleratedRendering() const { return m_player && m_player->supportsAcceleratedRendering(); }
    161161
    162162    virtual bool isVideo() const { return false; }
     
    10691069
    10701070    RefPtr<MediaPlayer> m_player;
    1071     bool m_cachedSupportsAcceleratedRendering { false };
    10721071
    10731072    MediaPlayer::Preload m_preload { Preload::Auto };
  • trunk/Source/WebCore/rendering/RenderVideo.cpp

    r292049 r292290  
    231231        context.clip(contentRect);
    232232
    233     if (displayingPoster)
     233    if (displayingPoster) {
    234234        paintIntoRect(paintInfo, rect);
    235     else if (!videoElement().isFullscreen() || !videoElement().supportsAcceleratedRendering()) {
    236         if (paintInfo.paintBehavior.contains(PaintBehavior::FlattenCompositingLayers))
    237             context.paintFrameForMedia(*mediaPlayer, rect);
    238         else
    239             mediaPlayer->paint(context, rect);
    240     }
     235        return;
     236    }
     237
     238    if (!mediaPlayer)
     239        return;
     240
     241    // Painting contents during fullscreen playback causes stutters on iOS when the device is rotated.
     242    // https://bugs.webkit.org/show_bug.cgi?id=142097
     243    if (videoElement().supportsAcceleratedRendering() && videoElement().isFullscreen())
     244        return;
     245
     246    // Avoid unnecessary paints by skipping software painting if
     247    // the renderer is accelerated, and the paint operation does
     248    // not flatten compositing layers and is not snapshotting.
     249    if (hasAcceleratedCompositing()
     250        && videoElement().supportsAcceleratedRendering()
     251        && !paintInfo.paintBehavior.contains(PaintBehavior::FlattenCompositingLayers)
     252        && !paintInfo.paintBehavior.contains(PaintBehavior::Snapshotting))
     253        return;
     254
     255    context.paintFrameForMedia(*mediaPlayer, rect);
    241256}
    242257
Note: See TracChangeset for help on using the changeset viewer.