Title: [133786] trunk
Revision
133786
Author
p...@google.com
Date
2012-11-07 11:26:57 -0800 (Wed, 07 Nov 2012)

Log Message

Skip SVG repaint tracking when parent container transforms
https://bugs.webkit.org/show_bug.cgi?id=101177

Reviewed by Eric Seidel.

Source/WebCore:

This patch skips child repaint rect checks when a parent container is transformed, leading
to a 75% increase on the RoboHornet SVG benchmark:
    http://www.robohornet.org/#et=svg  (average of 2 runs)
    Before patch: 161.6ms
    After patch: 38.5ms

SVG transforms are relative to the local container which makes calculating an absolute
repaint rect expensive because it requires multiplying the local repaint rect by each
parent container's local transform. See SVGRenderSupport::computeFloatRectForRepaint
as an example of this calculation.

This patch takes advantage of SVG's container rules: when a parent container's transform
changes, all children must be repainted (there is no absolute positioning in SVG).
SVGRenderSupport::checkForSVGRepaintDuringLayout has been added which checks for whether
the parent transform changed before doing child repaint checks. A similar optimization is
used in HTML (see RenderObject::checkForRepaintDuringLayout) where no repaint checking
is done when the view is fully repainted.

This code is tested in existing tests.

* rendering/svg/RenderSVGContainer.cpp:
(WebCore::RenderSVGContainer::layout):
* rendering/svg/RenderSVGForeignObject.cpp:
(WebCore::RenderSVGForeignObject::layout):
* rendering/svg/RenderSVGImage.cpp:
(WebCore::RenderSVGImage::layout):
* rendering/svg/RenderSVGShape.cpp:
(WebCore::RenderSVGShape::layout):
* rendering/svg/RenderSVGText.cpp:
(WebCore::RenderSVGText::layout):
* rendering/svg/SVGRenderSupport.cpp:
(WebCore::SVGRenderSupport::checkForSVGRepaintDuringLayout):
(WebCore):
* rendering/svg/SVGRenderSupport.h:
(SVGRenderSupport):

LayoutTests:

The repaint area in svg/repaint/inner-svg-change-viewBox.svg has
been tightened as a result of this patch.

* platform/chromium/TestExpectations:
* platform/mac/TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (133785 => 133786)


--- trunk/LayoutTests/ChangeLog	2012-11-07 19:24:10 UTC (rev 133785)
+++ trunk/LayoutTests/ChangeLog	2012-11-07 19:26:57 UTC (rev 133786)
@@ -1,3 +1,16 @@
+2012-11-07  Philip Rogers  <p...@google.com>
+
+        Skip SVG repaint tracking when parent container transforms
+        https://bugs.webkit.org/show_bug.cgi?id=101177
+
+        Reviewed by Eric Seidel.
+
+        The repaint area in svg/repaint/inner-svg-change-viewBox.svg has
+        been tightened as a result of this patch.
+
+        * platform/chromium/TestExpectations:
+        * platform/mac/TestExpectations:
+
 2012-11-07  Balazs Kelemen  <kbal...@webkit.org>
 
         [Qt] Text on scaled layer is blurry

Modified: trunk/LayoutTests/platform/chromium/TestExpectations (133785 => 133786)


--- trunk/LayoutTests/platform/chromium/TestExpectations	2012-11-07 19:24:10 UTC (rev 133785)
+++ trunk/LayoutTests/platform/chromium/TestExpectations	2012-11-07 19:26:57 UTC (rev 133786)
@@ -3990,6 +3990,10 @@
 # Requires rebaselining after https://bugs.webkit.org/show_bug.cgi?id=11645
 webkit.org/b/11645 fast/table/025.html [ Failure ]
 
+# Rebaseline required after https://bugs.webkit.org/show_bug.cgi?id=101177
+webkit.org/b/101177 svg/dynamic-updates/SVGUseElement-dom-requiredFeatures.html [ ImageOnlyFailure Pass ]
+webkit.org/b/101177 svg/repaint/inner-svg-change-viewBox.svg [ ImageOnlyFailure Pass ]
+
 # These are real failues due to 95121.
 # This is spilling caused by LANCZOS3 scaling algorithm that samples outside the source rect.
 webkit.org/b/95121 fast/images/pixel-crack-image-background-webkit-transform-scale.html [ ImageOnlyFailure ] 

Modified: trunk/LayoutTests/platform/mac/TestExpectations (133785 => 133786)


--- trunk/LayoutTests/platform/mac/TestExpectations	2012-11-07 19:24:10 UTC (rev 133785)
+++ trunk/LayoutTests/platform/mac/TestExpectations	2012-11-07 19:26:57 UTC (rev 133786)
@@ -1099,6 +1099,10 @@
 # Skip tests in fast/text/shaping
 webkit.org/b/90951 fast/text/shaping
 
+# Rebaseline required after https://bugs.webkit.org/show_bug.cgi?id=101177
+webkit.org/b/101177 svg/dynamic-updates/SVGUseElement-dom-requiredFeatures.html [ ImageOnlyFailure Pass ]
+webkit.org/b/101177 svg/repaint/inner-svg-change-viewBox.svg [ ImageOnlyFailure Pass ]
+
 webkit.org/b/93247 [ Debug ] fast/lists/list-marker-remove-crash.html [ Crash ]
 
 # (r124484) inspector/device-orientation-success.html failing on Mac ports

Modified: trunk/Source/WebCore/ChangeLog (133785 => 133786)


--- trunk/Source/WebCore/ChangeLog	2012-11-07 19:24:10 UTC (rev 133785)
+++ trunk/Source/WebCore/ChangeLog	2012-11-07 19:26:57 UTC (rev 133786)
@@ -1,3 +1,46 @@
+2012-11-07  Philip Rogers  <p...@google.com>
+
+        Skip SVG repaint tracking when parent container transforms
+        https://bugs.webkit.org/show_bug.cgi?id=101177
+
+        Reviewed by Eric Seidel.
+
+        This patch skips child repaint rect checks when a parent container is transformed, leading
+        to a 75% increase on the RoboHornet SVG benchmark:
+            http://www.robohornet.org/#et=svg  (average of 2 runs)
+            Before patch: 161.6ms
+            After patch: 38.5ms
+
+        SVG transforms are relative to the local container which makes calculating an absolute
+        repaint rect expensive because it requires multiplying the local repaint rect by each
+        parent container's local transform. See SVGRenderSupport::computeFloatRectForRepaint
+        as an example of this calculation.
+
+        This patch takes advantage of SVG's container rules: when a parent container's transform
+        changes, all children must be repainted (there is no absolute positioning in SVG).
+        SVGRenderSupport::checkForSVGRepaintDuringLayout has been added which checks for whether
+        the parent transform changed before doing child repaint checks. A similar optimization is
+        used in HTML (see RenderObject::checkForRepaintDuringLayout) where no repaint checking
+        is done when the view is fully repainted.
+
+        This code is tested in existing tests.
+
+        * rendering/svg/RenderSVGContainer.cpp:
+        (WebCore::RenderSVGContainer::layout):
+        * rendering/svg/RenderSVGForeignObject.cpp:
+        (WebCore::RenderSVGForeignObject::layout):
+        * rendering/svg/RenderSVGImage.cpp:
+        (WebCore::RenderSVGImage::layout):
+        * rendering/svg/RenderSVGShape.cpp:
+        (WebCore::RenderSVGShape::layout):
+        * rendering/svg/RenderSVGText.cpp:
+        (WebCore::RenderSVGText::layout):
+        * rendering/svg/SVGRenderSupport.cpp:
+        (WebCore::SVGRenderSupport::checkForSVGRepaintDuringLayout):
+        (WebCore):
+        * rendering/svg/SVGRenderSupport.h:
+        (SVGRenderSupport):
+
 2012-11-07  Chris Fleizach  <cfleiz...@apple.com>
 
         AX: Textfields don't get focus when navigated to from 'show all tabs' button

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGContainer.cpp (133785 => 133786)


--- trunk/Source/WebCore/rendering/svg/RenderSVGContainer.cpp	2012-11-07 19:24:10 UTC (rev 133785)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGContainer.cpp	2012-11-07 19:26:57 UTC (rev 133786)
@@ -57,7 +57,7 @@
     // RenderSVGRoot disables layoutState for the SVG rendering tree.
     ASSERT(!view()->layoutStateEnabled());
 
-    LayoutRepainter repainter(*this, checkForRepaintDuringLayout() || selfWillPaint());
+    LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this) || selfWillPaint());
 
     // Allow RenderSVGViewportContainer to update its viewport.
     calcViewport();

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp (133785 => 133786)


--- trunk/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp	2012-11-07 19:24:10 UTC (rev 133785)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp	2012-11-07 19:26:57 UTC (rev 133786)
@@ -127,7 +127,7 @@
     ASSERT(needsLayout());
     ASSERT(!view()->layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree.
 
-    LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+    LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this));
     SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
 
     bool updateCachedBoundariesInParents = false;

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGImage.cpp (133785 => 133786)


--- trunk/Source/WebCore/rendering/svg/RenderSVGImage.cpp	2012-11-07 19:24:10 UTC (rev 133785)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGImage.cpp	2012-11-07 19:26:57 UTC (rev 133786)
@@ -82,7 +82,7 @@
     StackStats::LayoutCheckPoint layoutCheckPoint;
     ASSERT(needsLayout());
 
-    LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout());
+    LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this) && selfNeedsLayout());
     updateImageViewport();
 
     bool transformOrBoundariesUpdate = m_needsTransformUpdate || m_needsBoundariesUpdate;

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp (133785 => 133786)


--- trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp	2012-11-07 19:24:10 UTC (rev 133785)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp	2012-11-07 19:26:57 UTC (rev 133786)
@@ -145,7 +145,7 @@
 void RenderSVGShape::layout()
 {
     StackStats::LayoutCheckPoint layoutCheckPoint;
-    LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout());
+    LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this) && selfNeedsLayout());
     SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
 
     bool updateCachedBoundariesInParents = false;

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp (133785 => 133786)


--- trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp	2012-11-07 19:24:10 UTC (rev 133785)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp	2012-11-07 19:26:57 UTC (rev 133786)
@@ -349,7 +349,7 @@
 {
     StackStats::LayoutCheckPoint layoutCheckPoint;
     ASSERT(needsLayout());
-    LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+    LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this));
 
     bool updateCachedBoundariesInParents = false;
     if (m_needsTransformUpdate) {

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp (133785 => 133786)


--- trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp	2012-11-07 19:24:10 UTC (rev 133785)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp	2012-11-07 19:26:57 UTC (rev 133786)
@@ -106,6 +106,16 @@
     return parent;
 }
 
+bool SVGRenderSupport::checkForSVGRepaintDuringLayout(RenderObject* object)
+{
+    if (!object->checkForRepaintDuringLayout())
+        return false;
+    // When a parent container is transformed in SVG, all children will be painted automatically
+    // so we are able to skip redundant repaint checks.
+    RenderObject* parent = object->parent();
+    return !(parent && parent->isSVGContainer() && toRenderSVGContainer(parent)->didTransformToRootUpdate());
+}
+
 // Update a bounding box taking into account the validity of the other bounding box.
 static inline void updateObjectBoundingBox(FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, RenderObject* other, FloatRect otherBoundingBox)
 {

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderSupport.h (133785 => 133786)


--- trunk/Source/WebCore/rendering/svg/SVGRenderSupport.h	2012-11-07 19:24:10 UTC (rev 133785)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderSupport.h	2012-11-07 19:26:57 UTC (rev 133786)
@@ -67,6 +67,7 @@
     static void computeFloatRectForRepaint(const RenderObject*, RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed);
     static void mapLocalToContainer(const RenderObject*, RenderLayerModelObject* repaintContainer, TransformState&, bool snapOffsetForTransforms = true, bool* wasFixed = 0);
     static const RenderObject* pushMappingToContainer(const RenderObject*, const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&);
+    static bool checkForSVGRepaintDuringLayout(RenderObject*);
 
     // Shared between SVG renderers and resources.
     static void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const RenderObject*);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to