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

Side by Side Diff: Source/core/rendering/svg/SVGRenderSupport.h

Issue 291243007: Make several functions in SVGRenderSupport templated for performance (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /** 1 /**
2 * Copyright (C) 2007 Rob Buis <buis@kde.org> 2 * Copyright (C) 2007 Rob Buis <buis@kde.org>
3 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
5 * Copyright (C) 2009 Google, Inc. All rights reserved. 5 * Copyright (C) 2009 Google, Inc. All rights reserved.
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version. 11 * version 2 of the License, or (at your option) any later version.
12 * 12 *
13 * This library is distributed in the hope that it will be useful, 13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details. 16 * Library General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU Library General Public License 18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to 19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA. 21 * Boston, MA 02110-1301, USA.
22 */ 22 */
23 23
24 #ifndef SVGRenderSupport_h 24 #ifndef SVGRenderSupport_h
25 #define SVGRenderSupport_h 25 #define SVGRenderSupport_h
26 26
27 #include "core/rendering/PaintInfo.h" 27 #include "core/rendering/PaintInfo.h"
28 #include "core/rendering/svg/RenderSVGRoot.h"
29 #include "core/rendering/svg/RenderSVGShape.h"
30 #include "core/rendering/svg/RenderSVGText.h"
31 #include "core/rendering/svg/RenderSVGViewportContainer.h"
32 #include "core/rendering/svg/SVGResources.h"
33 #include "core/rendering/svg/SVGResourcesCache.h"
28 34
29 namespace WebCore { 35 namespace WebCore {
30 36
31 class FloatPoint; 37 class FloatPoint;
32 class FloatRect; 38 class FloatRect;
33 class ImageBuffer; 39 class ImageBuffer;
34 class LayoutRect; 40 class LayoutRect;
35 class RenderBoxModelObject; 41 class RenderBoxModelObject;
36 class RenderGeometryMap; 42 class RenderGeometryMap;
37 class RenderLayerModelObject; 43 class RenderLayerModelObject;
38 class RenderObject; 44 class RenderObject;
39 class RenderStyle; 45 class RenderStyle;
40 class RenderSVGRoot; 46 class RenderSVGRoot;
41 class TransformState; 47 class TransformState;
42 48
43 namespace SVGRenderSupport { 49 class SVGRenderSupport {
44 // Shares child layouting code between RenderSVGRoot/RenderSVG(Hidden)Container 50 public:
45 void layoutChildren(RenderObject*, bool selfNeedsLayout); 51 // Shares child layouting code between RenderSVGRoot/RenderSVG(Hidden)Contai ner
52 template <typename RenderObjectType>
53 static void layoutChildren(RenderObjectType*, bool selfNeedsLayout);
46 54
47 // Layout resources used by this node. 55 // Layout resources used by this node.
48 void layoutResourcesIfNeeded(const RenderObject*); 56 static void layoutResourcesIfNeeded(const RenderObject*);
49 57
50 // Helper function determining wheter overflow is hidden 58 // Helper function determining wheter overflow is hidden
51 bool isOverflowHidden(const RenderObject*); 59 static bool isOverflowHidden(const RenderObject*);
52 60
53 // Calculates the repaintRect in combination with filter, clipper and masker in local coordinates. 61 // Calculates the repaintRect in combination with filter, clipper and masker in local coordinates.
54 void intersectRepaintRectWithResources(const RenderObject*, FloatRect&); 62 static void intersectRepaintRectWithResources(const RenderObject*, FloatRect &);
55 63
56 // Determines whether a container needs to be laid out because it's filtered and a child is being laid out. 64 // Determines whether a container needs to be laid out because it's filtered and a child is being laid out.
57 bool filtersForceContainerLayout(RenderObject*); 65 static bool filtersForceContainerLayout(RenderObject*);
58 66
59 // Determines whether the passed point lies in a clipping area 67 // Determines whether the passed point lies in a clipping area
60 bool pointInClippingArea(RenderObject*, const FloatPoint&); 68 static bool pointInClippingArea(RenderObject*, const FloatPoint&);
61 69
62 void computeContainerBoundingBoxes(const RenderObject* container, FloatRect& obj ectBoundingBox, bool& objectBoundingBoxValid, FloatRect& strokeBoundingBox, Floa tRect& repaintBoundingBox); 70 template <typename RenderObjectType>
63 bool paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const Aff ineTransform& localTransform, const PaintInfo&); 71 static void computeContainerBoundingBoxes(const RenderObjectType* container, FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, FloatRect& strokeBo undingBox, FloatRect& repaintBoundingBox);
64 72
65 // Important functions used by nearly all SVG renderers centralizing coordinate transformations / repaint rect calculations 73 static bool paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect , const AffineTransform& localTransform, const PaintInfo&);
66 LayoutRect clippedOverflowRectForRepaint(const RenderObject*, const RenderLayerM odelObject* repaintContainer);
67 void computeFloatRectForRepaint(const RenderObject*, const RenderLayerModelObjec t* repaintContainer, FloatRect&, bool fixed);
68 void mapLocalToContainer(const RenderObject*, const RenderLayerModelObject* repa intContainer, TransformState&, bool* wasFixed = 0);
69 const RenderObject* pushMappingToContainer(const RenderObject*, const RenderLaye rModelObject* ancestorToStopAt, RenderGeometryMap&);
70 bool checkForSVGRepaintDuringLayout(RenderObject*);
71 74
72 // Shared between SVG renderers and resources. 75 // Important functions used by nearly all SVG renderers centralizing coordin ate transformations / repaint rect calculations
73 void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const Rende rObject*); 76 static LayoutRect clippedOverflowRectForRepaint(const RenderObject*, const R enderLayerModelObject* repaintContainer);
74 void applyStrokeStyleToStrokeData(StrokeData*, const RenderStyle*, const RenderO bject*); 77 static void computeFloatRectForRepaint(const RenderObject*, const RenderLaye rModelObject* repaintContainer, FloatRect&, bool fixed);
78 static void mapLocalToContainer(const RenderObject*, const RenderLayerModelO bject* repaintContainer, TransformState&, bool* wasFixed = 0);
79 static const RenderObject* pushMappingToContainer(const RenderObject*, const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&);
80 static bool checkForSVGRepaintDuringLayout(RenderObject*);
75 81
76 // Determines if any ancestor's transform has changed. 82 // Shared between SVG renderers and resources.
77 bool transformToRootChanged(RenderObject*); 83 static void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const RenderObject*);
84 static void applyStrokeStyleToStrokeData(StrokeData*, const RenderStyle*, co nst RenderObject*);
78 85
79 // FIXME: These methods do not belong here. 86 // Determines if any ancestor's transform has changed.
80 const RenderSVGRoot* findTreeRootObject(const RenderObject*); 87 static bool transformToRootChanged(RenderObject*);
81 88
82 // Helper method for determining if a RenderObject marked as text (isText()== tr ue) 89 // FIXME: These methods do not belong here.
83 // can/will be rendered as part of a <text>. 90 static const RenderSVGRoot* findTreeRootObject(const RenderObject*);
84 bool isRenderableTextNode(const RenderObject*);
85 91
86 } // namespace SVGRenderSupport 92 // Helper method for determining if a RenderObject marked as text (isText()= = true)
93 // can/will be rendered as part of a <text>.
94 static bool isRenderableTextNode(const RenderObject*);
95
96 private:
97 static void updateObjectBoundingBox(FloatRect& objectBoundingBox, bool& obje ctBoundingBoxValid, RenderObject* other, FloatRect otherBoundingBox);
98 static void invalidateResourcesOfChildren(RenderObject* start);
99 static bool layoutSizeOfNearestViewportChanged(const RenderObject* start);
100 };
101
102 template <typename RenderObjectType>
103 void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObjectType* con tainer, FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, FloatRect& s trokeBoundingBox, FloatRect& repaintBoundingBox)
104 {
105 objectBoundingBox = FloatRect();
106 objectBoundingBoxValid = false;
107 strokeBoundingBox = FloatRect();
108
109 // When computing the strokeBoundingBox, we use the repaintRects of the cont ainer's children so that the container's stroke includes
110 // the resources applied to the children (such as clips and filters). This a llows filters applied to containers to correctly bound
111 // the children, and also improves inlining of SVG content, as the stroke bo und is used in that situation also.
112 for (RenderObject* current = container->firstChild(); current; current = cur rent->nextSibling()) {
113 if (current->isSVGHiddenContainer())
114 continue;
115
116 const AffineTransform& transform = current->localToParentTransform();
117 updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, curre nt,
118 transform.mapRect(current->objectBoundingBox()));
119 strokeBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoo rdinates()));
120 }
121
122 repaintBoundingBox = strokeBoundingBox;
123 }
124
125 template <typename RenderObjectType>
126 void SVGRenderSupport::layoutChildren(RenderObjectType* start, bool selfNeedsLay out)
127 {
128 bool layoutSizeChanged = layoutSizeOfNearestViewportChanged(start);
129 bool transformChanged = transformToRootChanged(start);
130 HashSet<RenderObject*> notlayoutedObjects;
131
132 for (RenderObject* child = start->firstChild(); child; child = child->nextSi bling()) {
133 bool needsLayout = selfNeedsLayout;
134 bool childEverHadLayout = child->everHadLayout();
135
136 if (transformChanged) {
137 // If the transform changed we need to update the text metrics (note : this also happens for layoutSizeChanged=true).
138 if (child->isSVGText())
139 toRenderSVGText(child)->setNeedsTextMetricsUpdate();
140 needsLayout = true;
141 }
142
143 if (layoutSizeChanged) {
144 // When selfNeedsLayout is false and the layout size changed, we hav e to check whether this child uses relative lengths
145 if (SVGElement* element = child->node()->isSVGElement() ? toSVGEleme nt(child->node()) : 0) {
146 if (element->hasRelativeLengths()) {
147 // When the layout size changed and when using relative valu es tell the RenderSVGShape to update its shape object
148 if (child->isSVGShape()) {
149 toRenderSVGShape(child)->setNeedsShapeUpdate();
150 } else if (child->isSVGText()) {
151 toRenderSVGText(child)->setNeedsTextMetricsUpdate();
152 toRenderSVGText(child)->setNeedsPositioningValuesUpdate( );
153 }
154
155 needsLayout = true;
156 }
157 }
158 }
159
160 SubtreeLayoutScope layoutScope(*child);
161 // Resource containers are nasty: they can invalidate clients outside th e current SubtreeLayoutScope.
162 // Since they only care about viewport size changes (to resolve their re lative lengths), we trigger
163 // their invalidation directly from SVGSVGElement::svgAttributeChange() or at a higher
164 // SubtreeLayoutScope (in RenderView::layout()).
165 if (needsLayout && !child->isSVGResourceContainer())
166 layoutScope.setNeedsLayout(child);
167
168 layoutResourcesIfNeeded(child);
169
170 if (child->needsLayout()) {
171 child->layout();
172 // Renderers are responsible for repainting themselves when changing , except
173 // for the initial paint to avoid potential double-painting caused b y non-sensical "old" bounds.
174 // We could handle this in the individual objects, but for now it's easier to have
175 // parent containers call repaint(). (RenderBlock::layout* has simi lar logic.)
176 if (!childEverHadLayout && !RuntimeEnabledFeatures::repaintAfterLayo utEnabled())
177 child->repaint();
178 } else if (layoutSizeChanged) {
179 notlayoutedObjects.add(child);
180 }
181 }
182
183 if (!layoutSizeChanged) {
184 ASSERT(notlayoutedObjects.isEmpty());
185 return;
186 }
187
188 // If the layout size changed, invalidate all resources of all children that didn't go through the layout() code path.
189 HashSet<RenderObject*>::iterator end = notlayoutedObjects.end();
190 for (HashSet<RenderObject*>::iterator it = notlayoutedObjects.begin(); it != end; ++it)
191 invalidateResourcesOfChildren(*it);
192 }
193
194 // Update a bounding box taking into account the validity of the other bounding box.
195 inline void SVGRenderSupport::updateObjectBoundingBox(FloatRect& objectBoundingB ox, bool& objectBoundingBoxValid, RenderObject* other, FloatRect otherBoundingBo x)
196 {
197 bool otherValid = other->isSVGContainer() ? toRenderSVGContainer(other)->isO bjectBoundingBoxValid() : true;
198 if (!otherValid)
199 return;
200
201 if (!objectBoundingBoxValid) {
202 objectBoundingBox = otherBoundingBox;
203 objectBoundingBoxValid = true;
204 return;
205 }
206
207 objectBoundingBox.uniteEvenIfEmpty(otherBoundingBox);
208 }
209
210 inline void SVGRenderSupport::invalidateResourcesOfChildren(RenderObject* start)
211 {
212 ASSERT(!start->needsLayout());
213 if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObj ect(start))
214 resources->removeClientFromCache(start, false);
215
216 for (RenderObject* child = start->slowFirstChild(); child; child = child->ne xtSibling())
217 invalidateResourcesOfChildren(child);
218 }
219
220 inline bool SVGRenderSupport::layoutSizeOfNearestViewportChanged(const RenderObj ect* start)
221 {
222 while (start && !start->isSVGRoot() && !start->isSVGViewportContainer())
223 start = start->parent();
224
225 ASSERT(start);
226 ASSERT(start->isSVGRoot() || start->isSVGViewportContainer());
227 if (start->isSVGViewportContainer())
228 return toRenderSVGViewportContainer(start)->isLayoutSizeChanged();
229
230 return toRenderSVGRoot(start)->isLayoutSizeChanged();
231 }
87 232
88 } // namespace WebCore 233 } // namespace WebCore
89 234
90 #endif // SVGRenderSupport_h 235 #endif // SVGRenderSupport_h
OLDNEW
« no previous file with comments | « Source/core/rendering/svg/SVGInlineTextBox.cpp ('k') | Source/core/rendering/svg/SVGRenderSupport.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698