- 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*);