YouTube embedding iframes in WebView sometimes go blank when the video starts playing
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Jul 2019 01:24:15 +0000 (01:24 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Jul 2019 01:24:15 +0000 (01:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=199600
rdar://problem/47806012

Reviewed by Tim Horton.

With some combinations of nested iframes that are being resized from empty, and toggling into
compositing mode, we'd fail to update compositing in the iframe's enclosing document, so never
host the iframes's layers.

Fix by moving some widget-resize-related code into RenderLayerCompositor::widgetDidChangeSize(),
and adding code to schedule a compositing update.

I was unable to come up with a layout test for this.

* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::widgetDidChangeSize):
* rendering/RenderLayerCompositor.h:
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::setWidgetGeometry):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247246 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderLayerCompositor.h
Source/WebCore/rendering/RenderWidget.cpp

index 44d9a10..52a21cd 100644 (file)
         (WebCore::MediaStreamTrack::~MediaStreamTrack):
         * Modules/mediastream/MediaStreamTrack.h:
 
+2019-07-08  Simon Fraser  <simon.fraser@apple.com>
+
+        YouTube embedding iframes in WebView sometimes go blank when the video starts playing
+        https://bugs.webkit.org/show_bug.cgi?id=199600
+        rdar://problem/47806012
+
+        Reviewed by Tim Horton.
+
+        With some combinations of nested iframes that are being resized from empty, and toggling into
+        compositing mode, we'd fail to update compositing in the iframe's enclosing document, so never
+        host the iframes's layers.
+
+        Fix by moving some widget-resize-related code into RenderLayerCompositor::widgetDidChangeSize(),
+        and adding code to schedule a compositing update.
+
+        I was unable to come up with a layout test for this.
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::widgetDidChangeSize):
+        * rendering/RenderLayerCompositor.h:
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::setWidgetGeometry):
+
 2019-07-08  Antoine Quint  <graouts@apple.com>
 
         [Pointer Events] Enable only on the most recent version of the supported iOS family
index b665968..7e4b376 100644 (file)
@@ -1985,6 +1985,24 @@ void RenderLayerCompositor::frameViewDidChangeSize()
     }
 }
 
+void RenderLayerCompositor::widgetDidChangeSize(RenderWidget& widget)
+{
+    if (!widget.hasLayer())
+        return;
+
+    auto& layer = *widget.layer();
+
+    LOG_WITH_STREAM(Compositing, stream << "RenderLayerCompositor " << this << " widgetDidChangeSize (layer " << &layer << ")");
+
+    // Widget size affects answer to requiresCompositingForFrame() so we need to trigger
+    // a compositing update.
+    layer.setNeedsPostLayoutCompositingUpdate();
+    scheduleCompositingLayerUpdate();
+
+    if (layer.isComposited())
+        layer.backing()->updateAfterWidgetResize();
+}
+
 bool RenderLayerCompositor::hasCoordinatedScrolling() const
 {
     auto* scrollingCoordinator = this->scrollingCoordinator();
index 1135951..069ee97 100644 (file)
@@ -306,6 +306,8 @@ public:
     void frameViewDidLayout();
     void rootLayerConfigurationChanged();
 
+    void widgetDidChangeSize(RenderWidget&);
+
     String layerTreeAsText(LayerTreeFlags);
 
     float deviceScaleFactor() const override;
index dc24460..155d2cb 100644 (file)
@@ -141,8 +141,8 @@ bool RenderWidget::setWidgetGeometry(const LayoutRect& frame)
     if (!weakThis)
         return true;
 
-    if (boundsChanged && isComposited())
-        layer()->backing()->updateAfterWidgetResize();
+    if (boundsChanged)
+        view().compositor().widgetDidChangeSize(*this);
 
     return oldFrameRect.size() != newFrameRect.size();
 }