Changeset 224297 in webkit


Ignore:
Timestamp:
Nov 1, 2017 2:41:59 PM (6 years ago)
Author:
jer.noble@apple.com
Message:

[Performance] Painting <video> to canvas spends a lot of time in URL getting and parsing
https://bugs.webkit.org/show_bug.cgi?id=179131

Reviewed by Eric Carlson.

Every time a <video> backed by MediaPlayerPrivateAVFoundation is asked to paint, it is first
queried whether it has a single security origin. To do this, the media player asks
AVFoundation what the "resolvedURL" of the asset is. This answer never changes after
metadata is first fetched, so the answer should be cached. To do so, add a m_resolvedURL
ivar to MediaPlayerPrivateAVFoundation, and add a setResolvedURL() and resolvedURLChanged()
method to re-query the value. Also create ivars for the security origin rather than re-
parsing them every time.

Drive-by fix: clean up all the instances where we pass a String rather than a URL (and thus
have to re-parse the URL at each point).

  • platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:

(WebCore::MediaPlayerPrivateAVFoundation::load):
(WebCore::MediaPlayerPrivateAVFoundation::hasSingleSecurityOrigin const):
(WebCore::MediaPlayerPrivateAVFoundation::setResolvedURL):
(WebCore::MediaPlayerPrivateAVFoundation::metadataLoaded):
(WebCore::MediaPlayerPrivateAVFoundation::setPreload):
(WebCore::MediaPlayerPrivateAVFoundation::resolvedURL const): Deleted.

  • platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:

(WebCore::MediaPlayerPrivateAVFoundation::resolvedURL const):

  • platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp:

(WebCore::MediaPlayerPrivateAVFoundationCF::resolvedURLChanged):
(WebCore::AVFWrapper::createAssetForURL):
(WebCore::MediaPlayerPrivateAVFoundationCF::resolvedURL const): Deleted.
(WebCore::MediaPlayerPrivateAVFoundationCF::hasSingleSecurityOrigin const): Deleted.

  • platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h:
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:

(WebCore::canonicalURL):
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL):
(WebCore::MediaPlayerPrivateAVFoundationObjC::sizeChanged):
(WebCore::canonicalURL):
(WebCore::MediaPlayerPrivateAVFoundationObjC::hasSingleSecurityOrigin const): Deleted.

Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r224296 r224297  
     12017-11-01  Jer Noble  <jer.noble@apple.com>
     2
     3        [Performance] Painting <video> to canvas spends a lot of time in URL getting and parsing
     4        https://bugs.webkit.org/show_bug.cgi?id=179131
     5
     6        Reviewed by Eric Carlson.
     7
     8        Every time a <video> backed by MediaPlayerPrivateAVFoundation is asked to paint, it is first
     9        queried whether it has a single security origin. To do this, the media player asks
     10        AVFoundation what the "resolvedURL" of the asset is. This answer never changes after
     11        metadata is first fetched, so the answer should be cached. To do so, add a m_resolvedURL
     12        ivar to MediaPlayerPrivateAVFoundation, and add a setResolvedURL() and resolvedURLChanged()
     13        method to re-query the value. Also create ivars for the security origin rather than re-
     14        parsing them every time.
     15
     16        Drive-by fix: clean up all the instances where we pass a String rather than a URL (and thus
     17        have to re-parse the URL at each point).
     18
     19        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
     20        (WebCore::MediaPlayerPrivateAVFoundation::load):
     21        (WebCore::MediaPlayerPrivateAVFoundation::hasSingleSecurityOrigin const):
     22        (WebCore::MediaPlayerPrivateAVFoundation::setResolvedURL):
     23        (WebCore::MediaPlayerPrivateAVFoundation::metadataLoaded):
     24        (WebCore::MediaPlayerPrivateAVFoundation::setPreload):
     25        (WebCore::MediaPlayerPrivateAVFoundation::resolvedURL const): Deleted.
     26        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
     27        (WebCore::MediaPlayerPrivateAVFoundation::resolvedURL const):
     28        * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp:
     29        (WebCore::MediaPlayerPrivateAVFoundationCF::resolvedURLChanged):
     30        (WebCore::AVFWrapper::createAssetForURL):
     31        (WebCore::MediaPlayerPrivateAVFoundationCF::resolvedURL const): Deleted.
     32        (WebCore::MediaPlayerPrivateAVFoundationCF::hasSingleSecurityOrigin const): Deleted.
     33        * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h:
     34        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
     35        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
     36        (WebCore::canonicalURL):
     37        (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL):
     38        (WebCore::MediaPlayerPrivateAVFoundationObjC::sizeChanged):
     39        (WebCore::canonicalURL):
     40        (WebCore::MediaPlayerPrivateAVFoundationObjC::hasSingleSecurityOrigin const): Deleted.
     41
    1422017-11-01  Ryosuke Niwa  <rniwa@webkit.org>
    243
  • trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp

    r223720 r224297  
    173173    setReadyState(MediaPlayer::HaveNothing);
    174174
    175     m_assetURL = url;
     175    m_assetURL = URL(ParsedURLString, url);
     176    m_requestedOrigin = SecurityOrigin::create(m_assetURL);
    176177
    177178    // Don't do any more work if the url is empty.
     
    481482    return false;
    482483#endif
     484}
     485
     486bool MediaPlayerPrivateAVFoundation::hasSingleSecurityOrigin() const
     487{
     488    if (m_resolvedOrigin && m_requestedOrigin)
     489        return m_resolvedOrigin->isSameSchemeHostPort(*m_requestedOrigin);
     490    return false;
     491}
     492
     493void MediaPlayerPrivateAVFoundation::setResolvedURL(URL&& resolvedURL)
     494{
     495    m_resolvedURL = WTFMove(resolvedURL);
     496    m_resolvedOrigin = SecurityOrigin::create(m_resolvedURL);
    483497}
    484498
     
    612626{
    613627    m_loadingMetadata = false;
     628    resolvedURLChanged();
    614629    tracksChanged();
    615630}
     
    721736    ALWAYS_LOG(LOGIDENTIFIER, " - ", static_cast<int>(preload));
    722737    m_preload = preload;
    723     if (!m_assetURL.length())
     738    if (m_assetURL.isEmpty())
    724739        return;
    725740
     
    10451060}
    10461061#endif
    1047 
    1048 URL MediaPlayerPrivateAVFoundation::resolvedURL() const
    1049 {
    1050     if (!m_assetURL.length())
    1051         return URL();
    1052 
    1053     return URL(ParsedURLString, m_assetURL);
    1054 }
    10551062
    10561063bool MediaPlayerPrivateAVFoundation::canSaveMediaData() const
  • trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h

    r222422 r224297  
    220220    unsigned long long fileSize() const override { return totalBytes(); }
    221221
     222    bool hasSingleSecurityOrigin() const override;
     223
    222224    // Required interfaces for concrete derived classes.
    223     virtual void createAVAssetForURL(const String&) = 0;
     225    virtual void createAVAssetForURL(const URL&) = 0;
    224226    virtual void createAVPlayer() = 0;
    225227    virtual void createAVPlayerItem() = 0;
     
    275277
    276278    virtual void updateVideoLayerGravity() = 0;
     279    virtual void resolvedURLChanged() = 0;
    277280
    278281    static bool isUnsupportedMIMEType(const String&);
     
    327330    Vector<RefPtr<InbandTextTrackPrivateAVF>> m_textTracks;
    328331
    329     virtual URL resolvedURL() const;
     332    void setResolvedURL(URL&&);
     333    const URL& resolvedURL() const { return m_resolvedURL; }
    330334
    331335private:
     
    344348    MediaPlayer::ReadyState m_readyState;
    345349
    346     String m_assetURL;
     350    URL m_assetURL;
     351    URL m_resolvedURL;
     352    RefPtr<SecurityOrigin> m_requestedOrigin;
     353    RefPtr<SecurityOrigin> m_resolvedOrigin;
     354
    347355    MediaPlayer::Preload m_preload;
    348356
  • trunk/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp

    r223476 r224297  
    11111111}
    11121112
     1113void MediaPlayerPrivateAVFoundationCF::resolvedURLChanged()
     1114{
     1115    if (m_avfWrapper && m_avfWrapper->avAsset())
     1116        setResolvedURL(adoptCF(AVCFAssetCopyResolvedURL(m_avfWrapper->avAsset())));
     1117    else
     1118        setResolvedURL({ });
     1119}
     1120
    11131121bool MediaPlayerPrivateAVFoundationCF::requiresImmediateCompositing() const
    11141122{
     
    13411349    if (m_avfWrapper)
    13421350        m_avfWrapper->setVideoLayerNeedsCommit();
    1343 }
    1344 
    1345 URL MediaPlayerPrivateAVFoundationCF::resolvedURL() const
    1346 {
    1347     if (!m_avfWrapper || !m_avfWrapper->avAsset())
    1348         return URL();
    1349 
    1350     auto resolvedURL = adoptCF(AVCFAssetCopyResolvedURL(m_avfWrapper->avAsset()));
    1351 
    1352     return URL(resolvedURL.get());
    1353 }
    1354 
    1355 bool MediaPlayerPrivateAVFoundationCF::hasSingleSecurityOrigin() const
    1356 {
    1357     if (!m_avfWrapper || !m_avfWrapper->avAsset())
    1358         return false;
    1359 
    1360     Ref<SecurityOrigin> resolvedOrigin(SecurityOrigin::create(resolvedURL()));
    1361     Ref<SecurityOrigin> requestedOrigin(SecurityOrigin::createFromString(assetURL()));
    1362     return resolvedOrigin->isSameSchemeHostPort(requestedOrigin.get());
    13631351}
    13641352
     
    15111499}
    15121500
    1513 void AVFWrapper::createAssetForURL(const String& url, bool inheritURI)
     1501void AVFWrapper::createAssetForURL(const URL& url, bool inheritURI)
    15141502{
    15151503    ASSERT(!avAsset());
    15161504
    1517     RetainPtr<CFURLRef> urlRef = URL(ParsedURLString, url).createCFURL();
     1505    RetainPtr<CFURLRef> urlRef = url.createCFURL();
    15181506
    15191507    RetainPtr<CFMutableDictionaryRef> optionsRef = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
  • trunk/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h

    r222946 r224297  
    4747
    4848    void tracksChanged() override;
     49    void resolvedURLChanged() override;
    4950
    5051#if HAVE(AVFOUNDATION_LOADER_DELEGATE)
     
    8485    virtual void createAVPlayer();
    8586    virtual void createAVPlayerItem();
    86     virtual void createAVAssetForURL(const String& url);
     87    virtual void createAVAssetForURL(const URL&);
    8788    virtual MediaPlayerPrivateAVFoundation::ItemStatus playerItemStatus() const;
    8889    virtual MediaPlayerPrivateAVFoundation::AssetStatus assetStatus() const;
     
    116117
    117118    virtual void contentsNeedsDisplay();
    118 
    119     URL resolvedURL() const override;
    120 
    121     bool hasSingleSecurityOrigin() const override;
    122119
    123120#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h

    r222946 r224297  
    206206    void createAVPlayerItem() override;
    207207    virtual void createAVPlayerLayer();
    208     void createAVAssetForURL(const String& url) override;
     208    void createAVAssetForURL(const URL&) override;
    209209    MediaPlayerPrivateAVFoundation::ItemStatus playerItemStatus() const override;
    210210    MediaPlayerPrivateAVFoundation::AssetStatus assetStatus() const override;
     
    227227    void beginLoadingMetadata() override;
    228228    void sizeChanged() override;
     229    void resolvedURLChanged() override;
    229230
    230231    bool hasAvailableVideoFrame() const override;
     
    241242    void updateVideoLayerGravity() override;
    242243
    243     bool hasSingleSecurityOrigin() const override;
    244244    bool didPassCORSAccessCheck() const override;
    245245
     
    330330    double maxFastForwardRate() const override { return m_cachedCanPlayFastForward ? std::numeric_limits<double>::infinity() : 2.0; }
    331331    double minFastReverseRate() const override { return m_cachedCanPlayFastReverse ? -std::numeric_limits<double>::infinity() : 0.0; }
    332 
    333     URL resolvedURL() const override;
    334332
    335333    Vector<String> preferredAudioCharacteristics() const;
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm

    r223720 r224297  
    874874
    875875
    876 static NSURL *canonicalURL(const String& url)
    877 {
    878     NSURL *cocoaURL = URL(ParsedURLString, url);
     876static NSURL *canonicalURL(const URL& url)
     877{
     878    NSURL *cocoaURL = url;
    879879    if (url.isEmpty())
    880880        return cocoaURL;
     
    911911#endif
    912912
    913 void MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL(const String& url)
     913void MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL(const URL& url)
    914914{
    915915    if (m_avAsset)
     
    991991#if PLATFORM(IOS)
    992992    Vector<Cookie> cookies;
    993     if (player()->getRawCookies(URL(ParsedURLString, url), cookies)) {
     993    if (player()->getRawCookies(url, cookies)) {
    994994        RetainPtr<NSMutableArray> nsCookies = adoptNS([[NSMutableArray alloc] initWithCapacity:cookies.size()]);
    995995        for (auto& cookie : cookies)
     
    22872287    setNaturalSize(m_cachedPresentationSize);
    22882288}
    2289    
    2290 bool MediaPlayerPrivateAVFoundationObjC::hasSingleSecurityOrigin() const
    2291 {
    2292     if (!m_avAsset || [m_avAsset statusOfValueForKey:@"resolvedURL" error:nullptr] != AVKeyValueStatusLoaded)
    2293         return false;
    2294    
    2295     Ref<SecurityOrigin> resolvedOrigin(SecurityOrigin::create(resolvedURL()));
    2296     Ref<SecurityOrigin> requestedOrigin(SecurityOrigin::createFromString(assetURL()));
    2297     return resolvedOrigin->isSameSchemeHostPort(requestedOrigin.get());
     2289
     2290void MediaPlayerPrivateAVFoundationObjC::resolvedURLChanged()
     2291{
     2292    setResolvedURL(m_avAsset ? URL([m_avAsset resolvedURL]) : URL());
    22982293}
    22992294
     
    32913286{
    32923287    m_cachedCanPlayFastReverse = newValue;
    3293 }
    3294 
    3295 URL MediaPlayerPrivateAVFoundationObjC::resolvedURL() const
    3296 {
    3297     if (!m_avAsset || [m_avAsset statusOfValueForKey:@"resolvedURL" error:nullptr] != AVKeyValueStatusLoaded)
    3298         return MediaPlayerPrivateAVFoundation::resolvedURL();
    3299 
    3300     return URL([m_avAsset resolvedURL]);
    33013288}
    33023289
Note: See TracChangeset for help on using the changeset viewer.