Title: [264069] releases/WebKitGTK/webkit-2.28/Source/WebCore
Revision
264069
Author
[email protected]
Date
2020-07-08 02:01:53 -0700 (Wed, 08 Jul 2020)

Log Message

Merge r258278 - SVG filter triggers unstable layout.
https://bugs.webkit.org/show_bug.cgi?id=207444
rdar://problem/59297004

Reviewed by Simon Fraser.

SVG filter code marks DOM nodes dirty and schedules style recalc outside of the SVG root
while in layout. This could lead to unstable layout and cause battery drain.
(See webkit.org/b/208903)

* rendering/RenderLayer.cpp: Remove filterNeedsRepaint(). It's a dangerously misleading name and should
not be part of RenderLayer.
(WebCore::RenderLayer::calculateClipRects const):
* rendering/RenderLayer.h:
* rendering/RenderLayerFilters.cpp:
(WebCore::RenderLayerFilters::notifyFinished):
* rendering/svg/RenderSVGResourceContainer.cpp:
(WebCore::RenderSVGResourceContainer::markAllClientsForInvalidation):
(WebCore::RenderSVGResourceContainer::markAllClientLayersForInvalidation):

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog (264068 => 264069)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog	2020-07-08 09:01:47 UTC (rev 264068)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog	2020-07-08 09:01:53 UTC (rev 264069)
@@ -1,3 +1,25 @@
+2020-03-11  Zalan Bujtas  <[email protected]>
+
+        SVG filter triggers unstable layout.
+        https://bugs.webkit.org/show_bug.cgi?id=207444
+        rdar://problem/59297004
+
+        Reviewed by Simon Fraser.
+
+        SVG filter code marks DOM nodes dirty and schedules style recalc outside of the SVG root
+        while in layout. This could lead to unstable layout and cause battery drain.
+        (See webkit.org/b/208903)
+
+        * rendering/RenderLayer.cpp: Remove filterNeedsRepaint(). It's a dangerously misleading name and should
+        not be part of RenderLayer.
+        (WebCore::RenderLayer::calculateClipRects const):
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerFilters.cpp:
+        (WebCore::RenderLayerFilters::notifyFinished):
+        * rendering/svg/RenderSVGResourceContainer.cpp:
+        (WebCore::RenderSVGResourceContainer::markAllClientsForInvalidation):
+        (WebCore::RenderSVGResourceContainer::markAllClientLayersForInvalidation):
+
 2020-03-13  Said Abou-Hallawa  <[email protected]>
 
         SVGMatrix should have the access right of its owner SVGTransform always

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayer.cpp (264068 => 264069)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayer.cpp	2020-07-08 09:01:47 UTC (rev 264068)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayer.cpp	2020-07-08 09:01:53 UTC (rev 264069)
@@ -6911,16 +6911,6 @@
     m_filters->buildFilter(renderer(), page().deviceScaleFactor(), renderer().settings().acceleratedFiltersEnabled() ? RenderingMode::Accelerated : RenderingMode::Unaccelerated);
 }
 
-void RenderLayer::filterNeedsRepaint()
-{
-    // We use the enclosing element so that we recalculate style for the ancestor of an anonymous object.
-    if (Element* element = enclosingElement()) {
-        // FIXME: This really shouldn't have to invalidate layer composition, but tests like css3/filters/effect-reference-delete.html fail if that doesn't happen.
-        element->invalidateStyleAndLayerComposition();
-    }
-    renderer().repaint();
-}
-
 IntOutsets RenderLayer::filterOutsets() const
 {
     if (m_filters)

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayer.h (264068 => 264069)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayer.h	2020-07-08 09:01:47 UTC (rev 264068)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayer.h	2020-07-08 09:01:53 UTC (rev 264069)
@@ -796,7 +796,6 @@
     bool has3DTransform() const { return m_transform && !m_transform->isAffine(); }
     bool hasTransformedAncestor() const { return m_hasTransformedAncestor; }
 
-    void filterNeedsRepaint();
     bool hasFilter() const { return renderer().hasFilter(); }
     bool hasFilterOutsets() const { return !filterOutsets().isZero(); }
     IntOutsets filterOutsets() const;

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayerFilters.cpp (264068 => 264069)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayerFilters.cpp	2020-07-08 09:01:47 UTC (rev 264068)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/RenderLayerFilters.cpp	2020-07-08 09:01:53 UTC (rev 264069)
@@ -67,7 +67,11 @@
 
 void RenderLayerFilters::notifyFinished(CachedResource&)
 {
-    m_layer.filterNeedsRepaint();
+    // FIXME: This really shouldn't have to invalidate layer composition,
+    // but tests like css3/filters/effect-reference-delete.html fail if that doesn't happen.
+    if (auto* enclosingElement = m_layer.enclosingElement())
+        enclosingElement->invalidateStyleAndLayerComposition();
+    m_layer.renderer().repaint();
 }
 
 void RenderLayerFilters::updateReferenceFilterClients(const FilterOperations& operations)

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp (264068 => 264069)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp	2020-07-08 09:01:47 UTC (rev 264068)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp	2020-07-08 09:01:53 UTC (rev 264069)
@@ -26,6 +26,7 @@
 #include "SVGRenderingContext.h"
 #include "SVGResourcesCache.h"
 #include <wtf/IsoMallocInlines.h>
+#include <wtf/SetForScope.h>
 #include <wtf/StackStats.h>
 
 namespace WebCore {
@@ -91,10 +92,13 @@
 
 void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode mode)
 {
+    // FIXME: Style invalidation should either be a pre-layout task or this function
+    // should never get called while in layout. See webkit.org/b/208903.
     if ((m_clients.isEmpty() && m_clientLayers.isEmpty()) || m_isInvalidating)
         return;
 
-    m_isInvalidating = true;
+    SetForScope<bool> isInvalidating(m_isInvalidating, true);
+
     bool needsLayout = mode == LayoutAndBoundariesInvalidation;
     bool markForInvalidation = mode != ParentOnlyInvalidation;
     auto* root = SVGRenderSupport::findTreeRootObject(*this);
@@ -116,8 +120,6 @@
     }
 
     markAllClientLayersForInvalidation();
-
-    m_isInvalidating = false;
 }
 
 void RenderSVGResourceContainer::markAllClientLayersForInvalidation()
@@ -124,10 +126,23 @@
 {
     if (m_clientLayers.isEmpty())
         return;
-    if ((*m_clientLayers.begin())->renderer().renderTreeBeingDestroyed())
+
+    auto& document = (*m_clientLayers.begin())->renderer().document();
+    if (!document.view() || document.renderTreeBeingDestroyed())
         return;
-    for (auto* clientLayer : m_clientLayers)
-        clientLayer->filterNeedsRepaint();
+
+    auto inLayout = document.view()->layoutContext().isInLayout();
+    for (auto* clientLayer : m_clientLayers) {
+        // FIXME: We should not get here while in layout. See webkit.org/b/208903.
+        // Repaint should also be triggered through some other means.
+        if (inLayout) {
+            clientLayer->renderer().repaint();
+            continue;
+        }
+        if (auto* enclosingElement = clientLayer->enclosingElement())
+            enclosingElement->invalidateStyleAndLayerComposition();
+        clientLayer->renderer().repaint();
+    }
 }
 
 void RenderSVGResourceContainer::markClientForInvalidation(RenderObject& client, InvalidationMode mode)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to