Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(854)

Unified Diff: Source/core/rendering/svg/SVGRenderSupport.cpp

Issue 323043005: Partial revert of r174548: Make several functions in SVGRenderSupport templated for performance (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: win build fix Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/rendering/svg/SVGRenderSupport.h ('k') | Source/core/rendering/svg/SVGRenderTreeAsText.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/rendering/svg/SVGRenderSupport.cpp
diff --git a/Source/core/rendering/svg/SVGRenderSupport.cpp b/Source/core/rendering/svg/SVGRenderSupport.cpp
index 722c7164e069689af4adc9f5fab26a3a1da5cd91..f5b9c4d64cce15be5ce9aba4654e1d30e228d43f 100644
--- a/Source/core/rendering/svg/SVGRenderSupport.cpp
+++ b/Source/core/rendering/svg/SVGRenderSupport.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "core/rendering/svg/SVGRenderSupport.h"
+#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderGeometryMap.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/SubtreeLayoutScope.h"
@@ -32,6 +33,11 @@
#include "core/rendering/svg/RenderSVGResourceClipper.h"
#include "core/rendering/svg/RenderSVGResourceFilter.h"
#include "core/rendering/svg/RenderSVGResourceMasker.h"
+#include "core/rendering/svg/RenderSVGRoot.h"
+#include "core/rendering/svg/RenderSVGText.h"
+#include "core/rendering/svg/RenderSVGViewportContainer.h"
+#include "core/rendering/svg/SVGResources.h"
+#include "core/rendering/svg/SVGResourcesCache.h"
#include "core/svg/SVGElement.h"
#include "platform/geometry/TransformState.h"
@@ -104,6 +110,44 @@ bool SVGRenderSupport::checkForSVGRepaintDuringLayout(RenderObject* object)
return !(parent && parent->isSVGContainer() && toRenderSVGContainer(parent)->didTransformToRootUpdate());
}
+// Update a bounding box taking into account the validity of the other bounding box.
+inline void SVGRenderSupport::updateObjectBoundingBox(FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, RenderObject* other, FloatRect otherBoundingBox)
+{
+ bool otherValid = other->isSVGContainer() ? toRenderSVGContainer(other)->isObjectBoundingBoxValid() : true;
+ if (!otherValid)
+ return;
+
+ if (!objectBoundingBoxValid) {
+ objectBoundingBox = otherBoundingBox;
+ objectBoundingBoxValid = true;
+ return;
+ }
+
+ objectBoundingBox.uniteEvenIfEmpty(otherBoundingBox);
+}
+
+void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObject* container, FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, FloatRect& strokeBoundingBox, FloatRect& repaintBoundingBox)
+{
+ objectBoundingBox = FloatRect();
+ objectBoundingBoxValid = false;
+ strokeBoundingBox = FloatRect();
+
+ // When computing the strokeBoundingBox, we use the repaintRects of the container's children so that the container's stroke includes
+ // the resources applied to the children (such as clips and filters). This allows filters applied to containers to correctly bound
+ // the children, and also improves inlining of SVG content, as the stroke bound is used in that situation also.
+ for (RenderObject* current = container->slowFirstChild(); current; current = current->nextSibling()) {
+ if (current->isSVGHiddenContainer())
+ continue;
+
+ const AffineTransform& transform = current->localToParentTransform();
+ updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current,
+ transform.mapRect(current->objectBoundingBox()));
+ strokeBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates()));
+ }
+
+ repaintBoundingBox = strokeBoundingBox;
+}
+
bool SVGRenderSupport::paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo& paintInfo)
{
return localTransform.mapRect(localRepaintRect).intersects(paintInfo.rect);
@@ -119,6 +163,29 @@ const RenderSVGRoot* SVGRenderSupport::findTreeRootObject(const RenderObject* st
return toRenderSVGRoot(start);
}
+inline void SVGRenderSupport::invalidateResourcesOfChildren(RenderObject* start)
+{
+ ASSERT(!start->needsLayout());
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(start))
+ resources->removeClientFromCache(start, false);
+
+ for (RenderObject* child = start->slowFirstChild(); child; child = child->nextSibling())
+ invalidateResourcesOfChildren(child);
+}
+
+inline bool SVGRenderSupport::layoutSizeOfNearestViewportChanged(const RenderObject* start)
+{
+ while (start && !start->isSVGRoot() && !start->isSVGViewportContainer())
+ start = start->parent();
+
+ ASSERT(start);
+ ASSERT(start->isSVGRoot() || start->isSVGViewportContainer());
+ if (start->isSVGViewportContainer())
+ return toRenderSVGViewportContainer(start)->isLayoutSizeChanged();
+
+ return toRenderSVGRoot(start)->isLayoutSizeChanged();
+}
+
bool SVGRenderSupport::transformToRootChanged(RenderObject* ancestor)
{
while (ancestor && !ancestor->isSVGRoot()) {
@@ -132,6 +199,74 @@ bool SVGRenderSupport::transformToRootChanged(RenderObject* ancestor)
return false;
}
+void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
+{
+ bool layoutSizeChanged = layoutSizeOfNearestViewportChanged(start);
+ bool transformChanged = transformToRootChanged(start);
+ HashSet<RenderObject*> notlayoutedObjects;
+
+ for (RenderObject* child = start->slowFirstChild(); child; child = child->nextSibling()) {
+ bool needsLayout = selfNeedsLayout;
+ bool childEverHadLayout = child->everHadLayout();
+
+ if (transformChanged) {
+ // If the transform changed we need to update the text metrics (note: this also happens for layoutSizeChanged=true).
+ if (child->isSVGText())
+ toRenderSVGText(child)->setNeedsTextMetricsUpdate();
+ needsLayout = true;
+ }
+
+ if (layoutSizeChanged) {
+ // When selfNeedsLayout is false and the layout size changed, we have to check whether this child uses relative lengths
+ if (SVGElement* element = child->node()->isSVGElement() ? toSVGElement(child->node()) : 0) {
+ if (element->hasRelativeLengths()) {
+ // When the layout size changed and when using relative values tell the RenderSVGShape to update its shape object
+ if (child->isSVGShape()) {
+ toRenderSVGShape(child)->setNeedsShapeUpdate();
+ } else if (child->isSVGText()) {
+ toRenderSVGText(child)->setNeedsTextMetricsUpdate();
+ toRenderSVGText(child)->setNeedsPositioningValuesUpdate();
+ }
+
+ needsLayout = true;
+ }
+ }
+ }
+
+ SubtreeLayoutScope layoutScope(*child);
+ // Resource containers are nasty: they can invalidate clients outside the current SubtreeLayoutScope.
+ // Since they only care about viewport size changes (to resolve their relative lengths), we trigger
+ // their invalidation directly from SVGSVGElement::svgAttributeChange() or at a higher
+ // SubtreeLayoutScope (in RenderView::layout()).
+ if (needsLayout && !child->isSVGResourceContainer())
+ layoutScope.setNeedsLayout(child);
+
+ layoutResourcesIfNeeded(child);
+
+ if (child->needsLayout()) {
+ child->layout();
+ // Renderers are responsible for repainting themselves when changing, except
+ // for the initial paint to avoid potential double-painting caused by non-sensical "old" bounds.
+ // We could handle this in the individual objects, but for now it's easier to have
+ // parent containers call repaint(). (RenderBlock::layout* has similar logic.)
+ if (!childEverHadLayout && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ child->repaint();
+ } else if (layoutSizeChanged) {
+ notlayoutedObjects.add(child);
+ }
+ }
+
+ if (!layoutSizeChanged) {
+ ASSERT(notlayoutedObjects.isEmpty());
+ return;
+ }
+
+ // If the layout size changed, invalidate all resources of all children that didn't go through the layout() code path.
+ HashSet<RenderObject*>::iterator end = notlayoutedObjects.end();
+ for (HashSet<RenderObject*>::iterator it = notlayoutedObjects.begin(); it != end; ++it)
+ invalidateResourcesOfChildren(*it);
+}
+
void SVGRenderSupport::layoutResourcesIfNeeded(const RenderObject* object)
{
ASSERT(object);
« no previous file with comments | « Source/core/rendering/svg/SVGRenderSupport.h ('k') | Source/core/rendering/svg/SVGRenderTreeAsText.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698