Title: [184947] trunk/Source
Revision
184947
Author
[email protected]
Date
2015-05-28 00:34:21 -0700 (Thu, 28 May 2015)

Log Message

[iOS] When viewing an MJPEG stream as the main resource, only the first
frame paints

<https://bugs.webkit.org/show_bug.cgi?id=145185>
<rdar://problem/20124694>

Source/WebCore:

This bug is caused by state not being restored between successive loads
of multipart/x-mixed-replace content. Each part of the stream is not
treated as a wholly new load, so if state is cleared as part of the
previous page being destroyed, it may not be restored when loading
the next stream part.

On WK1, tile cache updates are disabled in FrameView::clear(), which is
called as the previous page is destroyed, but were not being
reenabled when loading new replacement content from the stream.

On WK2, the exposed content rect was being reset to an empty rect as
the previous page was destroyed, but it was not being reset by loading
replacement content.

To fix these issues, I added two WebFrameLoaderClient callbacks;
willReplaceMultipartContent() and didReplaceMultipartContent(). These
are used to save and restore state between successive loads.

Reviewed by Darin Adler.

* loader/DocumentLoader.cpp:
Call the new client callbacks.
(WebCore::DocumentLoader::commitLoad):
If replacing content in a multipart/x-mixed-replace stream, call the
WebFrameLoaderClient's didReplaceMultipartContent().

(WebCore::DocumentLoader::setupForReplace):
Call the WebFrameLoaderClient's willReplaceMultipartContent().

* loader/EmptyClients.h:

* loader/FrameLoaderClient.h:

* page/FrameView.cpp:
(WebCore::FrameView::didReplaceMultipartContent):
Re-enable tile cache updates that were disabled in FrameView::clear().
This fixes the issue for WK1.

* page/FrameView.h:
Declare an exported function, didReplaceMultipartContent(), that WebKit
can call.

Source/WebKit/mac:

Reviewed by Darin Adler.

* WebCoreSupport/WebFrameLoaderClient.h:

* WebCoreSupport/WebFrameLoaderClient.mm:
(WebFrameLoaderClient::didReplaceMultipartContent):
Call the FrameView's didReplaceMultipartContent().

Source/WebKit/win:

Reviewed by Darin Adler.

* WebCoreSupport/WebFrameLoaderClient.h:
Stubbed new functions that aren't used on Windows.

Source/WebKit2:

Reviewed by Darin Adler.

* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::willReplaceMultipartContent):
Tell the WebPage that we will replace multipart content.

(WebKit::WebFrameLoaderClient::didReplaceMultipartContent):
Tell the WebPage that we did replace multipart content.

* WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
* WebProcess/WebPage/DrawingArea.h:

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::willReplaceMultipartContent):
Save the exposed content rect.
(WebKit::WebPage::didReplaceMultipartContent):
Restore the exposed content rect that was saved before this load. This
fixes the issue for WK2.

* WebProcess/WebPage/WebPage.h:

* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::exposedContentRect):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (184946 => 184947)


--- trunk/Source/WebCore/ChangeLog	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebCore/ChangeLog	2015-05-28 07:34:21 UTC (rev 184947)
@@ -1,3 +1,53 @@
+2015-05-19  Jon Honeycutt  <[email protected]>
+
+        [iOS] When viewing an MJPEG stream as the main resource, only the first
+        frame paints
+
+        <https://bugs.webkit.org/show_bug.cgi?id=145185>
+        <rdar://problem/20124694>
+
+        This bug is caused by state not being restored between successive loads
+        of multipart/x-mixed-replace content. Each part of the stream is not
+        treated as a wholly new load, so if state is cleared as part of the
+        previous page being destroyed, it may not be restored when loading
+        the next stream part.
+
+        On WK1, tile cache updates are disabled in FrameView::clear(), which is
+        called as the previous page is destroyed, but were not being
+        reenabled when loading new replacement content from the stream.
+
+        On WK2, the exposed content rect was being reset to an empty rect as
+        the previous page was destroyed, but it was not being reset by loading
+        replacement content.
+
+        To fix these issues, I added two WebFrameLoaderClient callbacks;
+        willReplaceMultipartContent() and didReplaceMultipartContent(). These
+        are used to save and restore state between successive loads.
+
+        Reviewed by Darin Adler.
+
+        * loader/DocumentLoader.cpp:
+        Call the new client callbacks.
+        (WebCore::DocumentLoader::commitLoad):
+        If replacing content in a multipart/x-mixed-replace stream, call the
+        WebFrameLoaderClient's didReplaceMultipartContent().
+
+        (WebCore::DocumentLoader::setupForReplace):
+        Call the WebFrameLoaderClient's willReplaceMultipartContent().
+
+        * loader/EmptyClients.h:
+
+        * loader/FrameLoaderClient.h:
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::didReplaceMultipartContent):
+        Re-enable tile cache updates that were disabled in FrameView::clear().
+        This fixes the issue for WK1.
+
+        * page/FrameView.h:
+        Declare an exported function, didReplaceMultipartContent(), that WebKit
+        can call.
+
 2015-05-27  Brady Eidson  <[email protected]>
 
         Remove unused ResourceRequest "user initiated" flag.

Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (184946 => 184947)


--- trunk/Source/WebCore/loader/DocumentLoader.cpp	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp	2015-05-28 07:34:21 UTC (rev 184947)
@@ -762,6 +762,9 @@
         return;
 #endif
     frameLoader->client().committedLoad(this, data, length);
+
+    if (isMultipartReplacingLoad())
+        frameLoader->client().didReplaceMultipartContent();
 }
 
 ResourceError DocumentLoader::interruptedForPolicyChangeError() const
@@ -870,6 +873,8 @@
 {
     if (!mainResourceData())
         return;
+
+    frameLoader()->client().willReplaceMultipartContent();
     
     maybeFinishLoadingMultipartContent();
     maybeCreateArchive();

Modified: trunk/Source/WebCore/loader/EmptyClients.h (184946 => 184947)


--- trunk/Source/WebCore/loader/EmptyClients.h	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebCore/loader/EmptyClients.h	2015-05-28 07:34:21 UTC (rev 184947)
@@ -317,6 +317,9 @@
     virtual void willChangeTitle(DocumentLoader*) override { }
     virtual void didChangeTitle(DocumentLoader*) override { }
 
+    virtual void willReplaceMultipartContent() override { }
+    virtual void didReplaceMultipartContent() override { }
+
     virtual void committedLoad(DocumentLoader*, const char*, int) override { }
     virtual void finishedLoading(DocumentLoader*) override { }
 

Modified: trunk/Source/WebCore/loader/FrameLoaderClient.h (184946 => 184947)


--- trunk/Source/WebCore/loader/FrameLoaderClient.h	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebCore/loader/FrameLoaderClient.h	2015-05-28 07:34:21 UTC (rev 184947)
@@ -199,6 +199,9 @@
         virtual void willChangeTitle(DocumentLoader*) = 0;
         virtual void didChangeTitle(DocumentLoader*) = 0;
 
+        virtual void willReplaceMultipartContent() = 0;
+        virtual void didReplaceMultipartContent() = 0;
+
         virtual void committedLoad(DocumentLoader*, const char*, int) = 0;
         virtual void finishedLoading(DocumentLoader*) = 0;
         

Modified: trunk/Source/WebCore/page/FrameView.cpp (184946 => 184947)


--- trunk/Source/WebCore/page/FrameView.cpp	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebCore/page/FrameView.cpp	2015-05-28 07:34:21 UTC (rev 184947)
@@ -419,6 +419,15 @@
 #endif
 }
 
+#if PLATFORM(IOS)
+void FrameView::didReplaceMultipartContent()
+{
+    // Re-enable tile updates that were disabled in clear().
+    if (LegacyTileCache* tileCache = legacyTileCache())
+        tileCache->setTilingMode(LegacyTileCache::Normal);
+}
+#endif
+
 bool FrameView::didFirstLayout() const
 {
     return !m_firstLayout;

Modified: trunk/Source/WebCore/page/FrameView.h (184946 => 184947)


--- trunk/Source/WebCore/page/FrameView.h	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebCore/page/FrameView.h	2015-05-28 07:34:21 UTC (rev 184947)
@@ -345,6 +345,10 @@
     void willPaintContents(GraphicsContext*, const IntRect& dirtyRect, PaintingState&);
     void didPaintContents(GraphicsContext*, const IntRect& dirtyRect, PaintingState&);
 
+#if PLATFORM(IOS)
+    WEBCORE_EXPORT void didReplaceMultipartContent();
+#endif
+
     WEBCORE_EXPORT void setPaintBehavior(PaintBehavior);
     WEBCORE_EXPORT PaintBehavior paintBehavior() const;
     bool isPainting() const;

Modified: trunk/Source/WebKit/mac/ChangeLog (184946 => 184947)


--- trunk/Source/WebKit/mac/ChangeLog	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit/mac/ChangeLog	2015-05-28 07:34:21 UTC (rev 184947)
@@ -1,3 +1,19 @@
+2015-05-19  Jon Honeycutt  <[email protected]>
+
+        [iOS] When viewing an MJPEG stream as the main resource, only the first
+        frame paints
+
+        <https://bugs.webkit.org/show_bug.cgi?id=145185>
+        <rdar://problem/20124694>
+
+        Reviewed by Darin Adler.
+
+        * WebCoreSupport/WebFrameLoaderClient.h:
+
+        * WebCoreSupport/WebFrameLoaderClient.mm:
+        (WebFrameLoaderClient::didReplaceMultipartContent):
+        Call the FrameView's didReplaceMultipartContent().
+
 2015-05-22  Jon Lee  <[email protected]>
 
         Fix macros for wireless playback

Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.h (184946 => 184947)


--- trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.h	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.h	2015-05-28 07:34:21 UTC (rev 184947)
@@ -140,6 +140,9 @@
     virtual void willChangeTitle(WebCore::DocumentLoader*) override;
     virtual void didChangeTitle(WebCore::DocumentLoader*) override;
 
+    virtual void willReplaceMultipartContent() override { }
+    virtual void didReplaceMultipartContent() override;
+
     virtual void committedLoad(WebCore::DocumentLoader*, const char*, int) override;
     virtual void finishedLoading(WebCore::DocumentLoader*) override;
     virtual void updateGlobalHistory() override;

Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm (184946 => 184947)


--- trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm	2015-05-28 07:34:21 UTC (rev 184947)
@@ -999,6 +999,14 @@
 #endif
 }
 
+void WebFrameLoaderClient::didReplaceMultipartContent()
+{
+#if PLATFORM(IOS)
+    if (FrameView *view = core(m_webFrame.get())->view())
+        view->didReplaceMultipartContent();
+#endif
+}
+
 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
 {
     NSData *nsData = [[NSData alloc] initWithBytesNoCopy:(void*)data length:length freeWhenDone:NO];

Modified: trunk/Source/WebKit/win/ChangeLog (184946 => 184947)


--- trunk/Source/WebKit/win/ChangeLog	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit/win/ChangeLog	2015-05-28 07:34:21 UTC (rev 184947)
@@ -1,3 +1,16 @@
+2015-05-26  Jon Honeycutt  <[email protected]>
+
+        [iOS] When viewing an MJPEG stream as the main resource, only the first
+        frame paints
+
+        <https://bugs.webkit.org/show_bug.cgi?id=145185>
+        <rdar://problem/20124694>
+
+        Reviewed by Darin Adler.
+
+        * WebCoreSupport/WebFrameLoaderClient.h:
+        Stubbed new functions that aren't used on Windows.
+
 2015-05-22  Jon Lee  <[email protected]>
 
         Rename MediaPlaybackAllowsInline

Modified: trunk/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.h (184946 => 184947)


--- trunk/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.h	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.h	2015-05-28 07:34:21 UTC (rev 184947)
@@ -127,6 +127,9 @@
     virtual void willChangeTitle(WebCore::DocumentLoader*) override;
     virtual void didChangeTitle(WebCore::DocumentLoader*) override;
 
+    virtual void willReplaceMultipartContent() override { }
+    virtual void didReplaceMultipartContent() override { }
+
     virtual void updateGlobalHistory() override;
     virtual void updateGlobalHistoryRedirectLinks() override;
     virtual bool shouldGoToHistoryItem(WebCore::HistoryItem*) const override;

Modified: trunk/Source/WebKit2/ChangeLog (184946 => 184947)


--- trunk/Source/WebKit2/ChangeLog	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit2/ChangeLog	2015-05-28 07:34:21 UTC (rev 184947)
@@ -1,3 +1,36 @@
+2015-05-19  Jon Honeycutt  <[email protected]>
+
+        [iOS] When viewing an MJPEG stream as the main resource, only the first
+        frame paints
+
+        <https://bugs.webkit.org/show_bug.cgi?id=145185>
+        <rdar://problem/20124694>
+
+        Reviewed by Darin Adler.
+
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::willReplaceMultipartContent):
+        Tell the WebPage that we will replace multipart content.
+
+        (WebKit::WebFrameLoaderClient::didReplaceMultipartContent):
+        Tell the WebPage that we did replace multipart content.
+
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
+        * WebProcess/WebPage/DrawingArea.h:
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::willReplaceMultipartContent):
+        Save the exposed content rect.
+        (WebKit::WebPage::didReplaceMultipartContent):
+        Restore the exposed content rect that was saved before this load. This
+        fixes the issue for WK2.
+
+        * WebProcess/WebPage/WebPage.h:
+
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::RemoteLayerTreeDrawingArea::exposedContentRect):
+
 2015-05-22  Jon Lee  <[email protected]>
 
         Fix macros for wireless playback

Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (184946 => 184947)


--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp	2015-05-28 07:34:21 UTC (rev 184947)
@@ -913,6 +913,22 @@
     notImplemented();
 }
 
+void WebFrameLoaderClient::willReplaceMultipartContent()
+{
+    WebPage* webPage = m_frame->page();
+    if (!webPage)
+        return;
+    webPage->willReplaceMultipartContent(*m_frame);
+}
+
+void WebFrameLoaderClient::didReplaceMultipartContent()
+{
+    WebPage* webPage = m_frame->page();
+    if (!webPage)
+        return;
+    webPage->didReplaceMultipartContent(*m_frame);
+}
+
 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
 {
     if (!m_pluginView)

Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h (184946 => 184947)


--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h	2015-05-28 07:34:21 UTC (rev 184947)
@@ -123,7 +123,10 @@
     
     virtual void willChangeTitle(WebCore::DocumentLoader*) override;
     virtual void didChangeTitle(WebCore::DocumentLoader*) override;
-    
+
+    virtual void willReplaceMultipartContent() override;
+    virtual void didReplaceMultipartContent() override;
+
     virtual void committedLoad(WebCore::DocumentLoader*, const char*, int) override;
     virtual void finishedLoading(WebCore::DocumentLoader*) override;
     

Modified: trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h (184946 => 184947)


--- trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h	2015-05-28 07:34:21 UTC (rev 184947)
@@ -94,6 +94,7 @@
     virtual void addFence(const WebCore::MachSendRight&) { }
 #endif
 #if PLATFORM(IOS)
+    virtual WebCore::FloatRect exposedContentRect() const = 0;
     virtual void setExposedContentRect(const WebCore::FloatRect&) = 0;
 #endif
     virtual void mainFrameScrollabilityChanged(bool) { }

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (184946 => 184947)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2015-05-28 07:34:21 UTC (rev 184947)
@@ -4571,6 +4571,28 @@
     request->didCancel();
 }
 
+void WebPage::willReplaceMultipartContent(const WebFrame& frame)
+{
+#if PLATFORM(IOS)
+    if (!frame.isMainFrame())
+        return;
+
+    m_previousExposedContentRect = m_drawingArea->exposedContentRect();
+#endif
+}
+
+void WebPage::didReplaceMultipartContent(const WebFrame& frame)
+{
+#if PLATFORM(IOS)
+    if (!frame.isMainFrame())
+        return;
+
+    // Restore the previous exposed content rect so that it remains fixed when replacing content
+    // from multipart/x-mixed-replace streams.
+    m_drawingArea->setExposedContentRect(m_previousExposedContentRect);
+#endif
+}
+
 void WebPage::didCommitLoad(WebFrame* frame)
 {
     if (!frame->isMainFrame())

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (184946 => 184947)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2015-05-28 07:34:21 UTC (rev 184947)
@@ -253,6 +253,8 @@
     void didStartPageTransition();
     void didCompletePageTransition();
     void didCommitLoad(WebFrame*);
+    void willReplaceMultipartContent(const WebFrame&);
+    void didReplaceMultipartContent(const WebFrame&);
     void didFinishLoad(WebFrame*);
     void show();
     String userAgent(const WebCore::URL&) const;
@@ -1337,6 +1339,7 @@
     HashMap<std::pair<WebCore::IntSize, double>, WebCore::IntPoint> m_dynamicSizeUpdateHistory;
     RefPtr<WebCore::Node> m_pendingSyntheticClickNode;
     WebCore::FloatPoint m_pendingSyntheticClickLocation;
+    WebCore::FloatRect m_previousExposedContentRect;
 #endif
 
     WebInspectorClient* m_inspectorClient;

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h (184946 => 184947)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h	2015-05-28 07:34:21 UTC (rev 184947)
@@ -92,6 +92,7 @@
     virtual void acceleratedAnimationDidEnd(uint64_t layerID, const String& key) override;
 
 #if PLATFORM(IOS)
+    virtual WebCore::FloatRect exposedContentRect() const override;
     virtual void setExposedContentRect(const WebCore::FloatRect&) override;
 #endif
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm (184946 => 184947)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2015-05-28 07:27:13 UTC (rev 184946)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2015-05-28 07:34:21 UTC (rev 184947)
@@ -235,6 +235,15 @@
 }
 
 #if PLATFORM(IOS)
+WebCore::FloatRect RemoteLayerTreeDrawingArea::exposedContentRect() const
+{
+    FrameView* frameView = m_webPage.mainFrameView();
+    if (!frameView)
+        return FloatRect();
+
+    return frameView->exposedContentRect();
+}
+
 void RemoteLayerTreeDrawingArea::setExposedContentRect(const FloatRect& exposedContentRect)
 {
     FrameView* frameView = m_webPage.mainFrameView();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to