Title: [224297] trunk/Source/WebCore
Revision
224297
Author
jer.no...@apple.com
Date
2017-11-01 14:41:59 -0700 (Wed, 01 Nov 2017)

Log 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.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (224296 => 224297)


--- trunk/Source/WebCore/ChangeLog	2017-11-01 21:26:33 UTC (rev 224296)
+++ trunk/Source/WebCore/ChangeLog	2017-11-01 21:41:59 UTC (rev 224297)
@@ -1,3 +1,44 @@
+2017-11-01  Jer Noble  <jer.no...@apple.com>
+
+        [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.
+
 2017-11-01  Ryosuke Niwa  <rn...@webkit.org>
 
         innerText->renderBox() can be null in HTMLTextFormControlElement::setSelectionRange

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp (224296 => 224297)


--- trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp	2017-11-01 21:26:33 UTC (rev 224296)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp	2017-11-01 21:41:59 UTC (rev 224297)
@@ -172,7 +172,8 @@
     setNetworkState(m_preload == MediaPlayer::None ? MediaPlayer::Idle : MediaPlayer::Loading);
     setReadyState(MediaPlayer::HaveNothing);
 
-    m_assetURL = url;
+    m_assetURL = URL(ParsedURLString, url);
+    m_requestedOrigin = SecurityOrigin::create(m_assetURL);
 
     // Don't do any more work if the url is empty.
     if (!url.length())
@@ -482,6 +483,19 @@
 #endif
 }
 
+bool MediaPlayerPrivateAVFoundation::hasSingleSecurityOrigin() const
+{
+    if (m_resolvedOrigin && m_requestedOrigin)
+        return m_resolvedOrigin->isSameSchemeHostPort(*m_requestedOrigin);
+    return false;
+}
+
+void MediaPlayerPrivateAVFoundation::setResolvedURL(URL&& resolvedURL)
+{
+    m_resolvedURL = WTFMove(resolvedURL);
+    m_resolvedOrigin = SecurityOrigin::create(m_resolvedURL);
+}
+
 void MediaPlayerPrivateAVFoundation::updateStates()
 {
     if (m_ignoreLoadStateChanges)
@@ -611,6 +625,7 @@
 void MediaPlayerPrivateAVFoundation::metadataLoaded()
 {
     m_loadingMetadata = false;
+    resolvedURLChanged();
     tracksChanged();
 }
 
@@ -720,7 +735,7 @@
 {
     ALWAYS_LOG(LOGIDENTIFIER, " - ", static_cast<int>(preload));
     m_preload = preload;
-    if (!m_assetURL.length())
+    if (m_assetURL.isEmpty())
         return;
 
     setDelayCallbacks(true);
@@ -1045,14 +1060,6 @@
 }
 #endif
 
-URL MediaPlayerPrivateAVFoundation::resolvedURL() const
-{
-    if (!m_assetURL.length())
-        return URL();
-
-    return URL(ParsedURLString, m_assetURL);
-}
-
 bool MediaPlayerPrivateAVFoundation::canSaveMediaData() const
 {
     URL url = ""

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h (224296 => 224297)


--- trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h	2017-11-01 21:26:33 UTC (rev 224296)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h	2017-11-01 21:41:59 UTC (rev 224297)
@@ -219,8 +219,10 @@
     bool supportsScanning() const override { return true; }
     unsigned long long fileSize() const override { return totalBytes(); }
 
+    bool hasSingleSecurityOrigin() const override;
+
     // Required interfaces for concrete derived classes.
-    virtual void createAVAssetForURL(const String&) = 0;
+    virtual void createAVAssetForURL(const URL&) = 0;
     virtual void createAVPlayer() = 0;
     virtual void createAVPlayerItem() = 0;
 
@@ -274,6 +276,7 @@
     virtual bool hasLayerRenderer() const = 0;
 
     virtual void updateVideoLayerGravity() = 0;
+    virtual void resolvedURLChanged() = 0;
 
     static bool isUnsupportedMIMEType(const String&);
     static const HashSet<String, ASCIICaseInsensitiveHash>& staticMIMETypeList();
@@ -326,7 +329,8 @@
     void clearTextTracks();
     Vector<RefPtr<InbandTextTrackPrivateAVF>> m_textTracks;
 
-    virtual URL resolvedURL() const;
+    void setResolvedURL(URL&&);
+    const URL& resolvedURL() const { return m_resolvedURL; }
 
 private:
     MediaPlayer* m_player;
@@ -343,7 +347,11 @@
     MediaPlayer::NetworkState m_networkState;
     MediaPlayer::ReadyState m_readyState;
 
-    String m_assetURL;
+    URL m_assetURL;
+    URL m_resolvedURL;
+    RefPtr<SecurityOrigin> m_requestedOrigin;
+    RefPtr<SecurityOrigin> m_resolvedOrigin;
+
     MediaPlayer::Preload m_preload;
 
 #if !RELEASE_LOG_DISABLED

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp (224296 => 224297)


--- trunk/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp	2017-11-01 21:26:33 UTC (rev 224296)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp	2017-11-01 21:41:59 UTC (rev 224297)
@@ -1110,6 +1110,14 @@
     setNaturalSize(IntSize(naturalSize));
 }
 
+void MediaPlayerPrivateAVFoundationCF::resolvedURLChanged()
+{
+    if (m_avfWrapper && m_avfWrapper->avAsset())
+        setResolvedURL(adoptCF(AVCFAssetCopyResolvedURL(m_avfWrapper->avAsset())));
+    else
+        setResolvedURL({ });
+}
+
 bool MediaPlayerPrivateAVFoundationCF::requiresImmediateCompositing() const
 {
     // The AVFoundationCF player needs to have the root compositor available at construction time
@@ -1342,26 +1350,6 @@
         m_avfWrapper->setVideoLayerNeedsCommit();
 }
 
-URL MediaPlayerPrivateAVFoundationCF::resolvedURL() const
-{
-    if (!m_avfWrapper || !m_avfWrapper->avAsset())
-        return URL();
-
-    auto resolvedURL = adoptCF(AVCFAssetCopyResolvedURL(m_avfWrapper->avAsset()));
-
-    return URL(resolvedURL.get());
-}
-
-bool MediaPlayerPrivateAVFoundationCF::hasSingleSecurityOrigin() const
-{
-    if (!m_avfWrapper || !m_avfWrapper->avAsset())
-        return false;
-
-    Ref<SecurityOrigin> resolvedOrigin(SecurityOrigin::create(resolvedURL()));
-    Ref<SecurityOrigin> requestedOrigin(SecurityOrigin::createFromString(assetURL()));
-    return resolvedOrigin->isSameSchemeHostPort(requestedOrigin.get());
-}
-
 AVFWrapper::AVFWrapper(MediaPlayerPrivateAVFoundationCF* owner)
     : m_owner(owner)
     , m_objectID(s_nextAVFWrapperObjectID++)
@@ -1510,11 +1498,11 @@
     dispatch_async_f(dispatch_get_main_queue(), context, destroyAVFWrapper);
 }
 
-void AVFWrapper::createAssetForURL(const String& url, bool inheritURI)
+void AVFWrapper::createAssetForURL(const URL& url, bool inheritURI)
 {
     ASSERT(!avAsset());
 
-    RetainPtr<CFURLRef> urlRef = URL(ParsedURLString, url).createCFURL();
+    RetainPtr<CFURLRef> urlRef = url.createCFURL();
 
     RetainPtr<CFMutableDictionaryRef> optionsRef = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
 

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h (224296 => 224297)


--- trunk/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h	2017-11-01 21:26:33 UTC (rev 224296)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.h	2017-11-01 21:41:59 UTC (rev 224297)
@@ -46,6 +46,7 @@
     virtual ~MediaPlayerPrivateAVFoundationCF();
 
     void tracksChanged() override;
+    void resolvedURLChanged() override;
 
 #if HAVE(AVFOUNDATION_LOADER_DELEGATE)
     bool shouldWaitForLoadingOfResource(AVCFAssetResourceLoadingRequestRef);
@@ -83,7 +84,7 @@
 
     virtual void createAVPlayer();
     virtual void createAVPlayerItem();
-    virtual void createAVAssetForURL(const String& url);
+    virtual void createAVAssetForURL(const URL&);
     virtual MediaPlayerPrivateAVFoundation::ItemStatus playerItemStatus() const;
     virtual MediaPlayerPrivateAVFoundation::AssetStatus assetStatus() const;
 
@@ -116,10 +117,6 @@
 
     virtual void contentsNeedsDisplay();
 
-    URL resolvedURL() const override;
-
-    bool hasSingleSecurityOrigin() const override;
-
 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
     std::unique_ptr<LegacyCDMSession> createSession(const String&, LegacyCDMSessionClient*) override;
 #endif

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h (224296 => 224297)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h	2017-11-01 21:26:33 UTC (rev 224296)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h	2017-11-01 21:41:59 UTC (rev 224297)
@@ -205,7 +205,7 @@
     void createAVPlayer() override;
     void createAVPlayerItem() override;
     virtual void createAVPlayerLayer();
-    void createAVAssetForURL(const String& url) override;
+    void createAVAssetForURL(const URL&) override;
     MediaPlayerPrivateAVFoundation::ItemStatus playerItemStatus() const override;
     MediaPlayerPrivateAVFoundation::AssetStatus assetStatus() const override;
     long assetErrorCode() const override;
@@ -226,6 +226,7 @@
     MediaTime platformMaxTimeLoaded() const override;
     void beginLoadingMetadata() override;
     void sizeChanged() override;
+    void resolvedURLChanged() override;
 
     bool hasAvailableVideoFrame() const override;
 
@@ -240,7 +241,6 @@
 
     void updateVideoLayerGravity() override;
 
-    bool hasSingleSecurityOrigin() const override;
     bool didPassCORSAccessCheck() const override;
 
     MediaTime getStartDate() const override;
@@ -330,8 +330,6 @@
     double maxFastForwardRate() const override { return m_cachedCanPlayFastForward ? std::numeric_limits<double>::infinity() : 2.0; }
     double minFastReverseRate() const override { return m_cachedCanPlayFastReverse ? -std::numeric_limits<double>::infinity() : 0.0; }
 
-    URL resolvedURL() const override;
-
     Vector<String> preferredAudioCharacteristics() const;
 
     void setShouldDisableSleep(bool) override;

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (224296 => 224297)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2017-11-01 21:26:33 UTC (rev 224296)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2017-11-01 21:41:59 UTC (rev 224297)
@@ -873,9 +873,9 @@
 #endif
 
 
-static NSURL *canonicalURL(const String& url)
+static NSURL *canonicalURL(const URL& url)
 {
-    NSURL *cocoaURL = URL(ParsedURLString, url);
+    NSURL *cocoaURL = url;
     if (url.isEmpty())
         return cocoaURL;
 
@@ -910,7 +910,7 @@
 }
 #endif
 
-void MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL(const String& url)
+void MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL(const URL& url)
 {
     if (m_avAsset)
         return;
@@ -990,7 +990,7 @@
 
 #if PLATFORM(IOS)
     Vector<Cookie> cookies;
-    if (player()->getRawCookies(URL(ParsedURLString, url), cookies)) {
+    if (player()->getRawCookies(url, cookies)) {
         RetainPtr<NSMutableArray> nsCookies = adoptNS([[NSMutableArray alloc] initWithCapacity:cookies.size()]);
         for (auto& cookie : cookies)
             [nsCookies addObject:toNSHTTPCookie(cookie)];
@@ -2286,15 +2286,10 @@
 
     setNaturalSize(m_cachedPresentationSize);
 }
-    
-bool MediaPlayerPrivateAVFoundationObjC::hasSingleSecurityOrigin() const 
+
+void MediaPlayerPrivateAVFoundationObjC::resolvedURLChanged()
 {
-    if (!m_avAsset || [m_avAsset statusOfValueForKey:@"resolvedURL" error:nullptr] != AVKeyValueStatusLoaded)
-        return false;
-    
-    Ref<SecurityOrigin> resolvedOrigin(SecurityOrigin::create(resolvedURL()));
-    Ref<SecurityOrigin> requestedOrigin(SecurityOrigin::createFromString(assetURL()));
-    return resolvedOrigin->isSameSchemeHostPort(requestedOrigin.get());
+    setResolvedURL(m_avAsset ? URL([m_avAsset resolvedURL]) : URL());
 }
 
 bool MediaPlayerPrivateAVFoundationObjC::didPassCORSAccessCheck() const
@@ -3292,14 +3287,6 @@
     m_cachedCanPlayFastReverse = newValue;
 }
 
-URL MediaPlayerPrivateAVFoundationObjC::resolvedURL() const
-{
-    if (!m_avAsset || [m_avAsset statusOfValueForKey:@"resolvedURL" error:nullptr] != AVKeyValueStatusLoaded)
-        return MediaPlayerPrivateAVFoundation::resolvedURL();
-
-    return URL([m_avAsset resolvedURL]);
-}
-
 void MediaPlayerPrivateAVFoundationObjC::setShouldDisableSleep(bool flag)
 {
 #if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to