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

Side by Side Diff: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp

Issue 1407543003: Preliminary paint property walk implementation for SPv2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address the feedback Created 5 years, 2 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
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/paint/PaintPropertyTreeBuilder.h"
7
8 #include "core/frame/FrameView.h"
9 #include "core/layout/LayoutView.h"
10 #include "core/paint/ObjectPaintProperties.h"
11 #include "core/paint/PaintLayer.h"
12 #include "platform/graphics/paint/TransformPaintPropertyNode.h"
13 #include "platform/transforms/TransformationMatrix.h"
14
15 namespace blink {
16
17 // The context for layout tree walk.
18 // The walk will be done in the primary tree order (= DOM order), thus the conte xt will also be
19 // responsible for bookkeeping tree state in other order, for example, the most recent position
20 // container seen.
21 struct PaintPropertyTreeBuilder::Context {
22 Context() : currentTransform(nullptr), transformForOutOfFlowPositioned(nullp tr), transformForFixedPositioned(nullptr) { }
23
24 // The combination of a transform and paint offset describes a linear space.
25 // When a layout object recur to its children, the main context is expected to refer
26 // the object's border box, then the callee will derive its own border box b y translating
27 // the space with its own layout location.
28 TransformPaintPropertyNode* currentTransform;
29 LayoutPoint paintOffset;
30
31 // Separate context for out-of-flow positioned and fixed positioned elements are needed
32 // because they don't use DOM parent as their positioning parent (i.e. conta ining block).
33 // These additional contexts normally pass through untouched, and are only c opied from
34 // the main context when the current element serves as the positioning paren t of corresponding
35 // positioned descendants.
36 TransformPaintPropertyNode* transformForOutOfFlowPositioned;
37 LayoutPoint paintOffsetForOutOfFlowPositioned;
38
39 TransformPaintPropertyNode* transformForFixedPositioned;
40 LayoutPoint paintOffsetForFixedPositioned;
41 };
42
43 void PaintPropertyTreeBuilder::buildPropertyTrees(FrameView& rootFrame)
44 {
45 walk(rootFrame, Context());
46 }
47
48 void PaintPropertyTreeBuilder::walk(FrameView& frameView, const Context& context )
49 {
50 Context localContext(context);
51
52 TransformationMatrix frameTranslate;
53 frameTranslate.translate(frameView.x(), frameView.y());
54 // The frame owner applies paint offset already.
55 // This assumption may change in the future.
56 ASSERT(context.paintOffset == LayoutPoint());
57 RefPtr<TransformPaintPropertyNode> newTransformNodeForPreTranslation = Trans formPaintPropertyNode::create(frameTranslate, FloatPoint3D(), context.currentTra nsform);
58 localContext.transformForFixedPositioned = newTransformNodeForPreTranslation .get();
59 localContext.paintOffsetForFixedPositioned = LayoutPoint();
60
61 // This is going away in favor of Settings::rootLayerScrolls.
62 DoubleSize scrollOffset = frameView.scrollOffsetDouble();
63 TransformationMatrix frameScroll;
64 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height());
65 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create(frameScroll, FloatPoint3D(), newTransformNodeFo rPreTranslation);
66 localContext.currentTransform = localContext.transformForOutOfFlowPositioned = newTransformNodeForScrollTranslation.get();
67 localContext.paintOffset = localContext.paintOffsetForOutOfFlowPositioned = LayoutPoint();
68
69 frameView.setPreTranslation(newTransformNodeForPreTranslation.release());
70 frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release( ));
71
72 if (LayoutView* layoutView = frameView.layoutView())
73 walk(*layoutView, localContext);
74 }
75
76 static bool shouldCreatePaintOffsetTranslationNode(LayoutBoxModelObject& object)
77 {
78 // TODO(trchen): Eliminate PaintLayer dependency.
79 PaintLayer* layer = object.layer();
80 if (!layer)
81 return false;
82
83 return layer->paintsWithTransform(GlobalPaintNormalPhase);
84 }
85
86 static FloatPoint3D transformOrigin(const LayoutBox& box)
87 {
88 const ComputedStyle& style = box.styleRef();
89 FloatSize borderBoxSize(box.size());
90 return FloatPoint3D(
91 floatValueForLength(style.transformOriginX(), borderBoxSize.width()),
92 floatValueForLength(style.transformOriginY(), borderBoxSize.height()),
93 style.transformOriginZ());
94 }
95
96 static FloatPoint perspectiveOrigin(const LayoutBox& box)
97 {
98 const ComputedStyle& style = box.styleRef();
99 FloatSize borderBoxSize(box.size());
100 return FloatPoint(
101 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()),
102 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())) ;
103 }
104
105 void PaintPropertyTreeBuilder::walk(LayoutBoxModelObject& object, const Context& context)
chrishtr 2015/10/21 17:15:19 This function is too long.
pdr. 2015/10/21 17:18:02 @trchen, what do you think about breaking each ste
trchen 2015/10/21 22:21:14 Sure! I was thinking about it so we can use the fu
106 {
107 ASSERT(object.isBox() != object.isLayoutInline()); // Either or.
108
109 Context localContext(context);
110 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation ;
111 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform;
112 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective;
113 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation;
114
115 // * Figure out the layout space of the current object.
116 const ComputedStyle& style = object.styleRef();
117 // TODO(trchen): There is some insanity going on with tables. Double check r esults.
118 switch (style.position()) {
119 case StaticPosition:
120 break;
121 case RelativePosition:
122 localContext.paintOffset += object.offsetForInFlowPosition();
123 break;
124 case AbsolutePosition:
125 localContext.currentTransform = context.transformForOutOfFlowPositioned;
126 localContext.paintOffset = context.paintOffsetForOutOfFlowPositioned;
127 break;
128 case StickyPosition:
129 localContext.paintOffset += object.offsetForInFlowPosition();
130 break;
131 case FixedPosition:
132 localContext.currentTransform = context.transformForFixedPositioned;
133 localContext.paintOffset = context.paintOffsetForFixedPositioned;
134 break;
135 default:
136 ASSERT_NOT_REACHED();
137 }
138 if (object.isBox())
139 localContext.paintOffset += toLayoutBox(object).locationOffset();
140
141 // * Create a transform node to consolidate paint offset (if needed).
142 if (shouldCreatePaintOffsetTranslationNode(object) && localContext.paintOffs et != LayoutPoint()) {
143 TransformationMatrix matrix;
144 matrix.translate(localContext.paintOffset.x(), localContext.paintOffset. y());
145 newTransformNodeForPaintOffsetTranslation = TransformPaintPropertyNode:: create(
146 matrix, FloatPoint3D(), localContext.currentTransform);
147 localContext.currentTransform = newTransformNodeForPaintOffsetTranslatio n.get();
148 localContext.paintOffset = LayoutPoint();
149 }
150
151 // * Create a transform node for CSS transform (if present).
152 bool hasTransform = object.isBox() && style.hasTransform();
153 if (hasTransform) {
154 TransformationMatrix matrix;
155 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle:: ExcludeTransformOrigin,
156 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentT ransformProperties);
157 newTransformNodeForTransform = TransformPaintPropertyNode::create(
158 matrix, transformOrigin(toLayoutBox(object)), localContext.currentTr ansform);
159 localContext.currentTransform = newTransformNodeForTransform.get();
160 ASSERT(localContext.paintOffset == LayoutPoint());
161 }
162 // At this point, the current space is the space we paint the element itself .
163
164 // * Create a transform node for CSS perspective (if present).
165 if (object.isBox() && style.hasPerspective()) {
166 TransformationMatrix matrix;
167 matrix.applyPerspective(style.perspective());
168 newTransformNodeForPerspective = TransformPaintPropertyNode::create(
169 matrix, perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(localC ontext.paintOffset), localContext.currentTransform);
170 localContext.currentTransform = newTransformNodeForPerspective.get();
171 }
172
173 // * Create a transform node for overflow clip (if present).
174 if (object.hasOverflowClip()) {
175 PaintLayer* layer = object.layer();
176 ASSERT(layer);
177 DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset();
178 if (!scrollOffset.isZero() || layer->scrollsOverflow()) {
179 TransformationMatrix matrix;
180 matrix.translate(-scrollOffset.width(), -scrollOffset.height());
181 newTransformNodeForScrollTranslation = TransformPaintPropertyNode::c reate(matrix, FloatPoint3D(), localContext.currentTransform);
182 localContext.currentTransform = newTransformNodeForScrollTranslation .get();
183 }
184 }
185 // At this point, the current space is the space we paint in-flow children.
186
187 // * Update the context for out-of-flow descendants (if position container i s established).
188 if (style.position() != StaticPosition || hasTransform) {
189 localContext.transformForOutOfFlowPositioned = localContext.currentTrans form;
190 localContext.paintOffsetForOutOfFlowPositioned = localContext.paintOffse t;
191 }
192 if (hasTransform) {
193 localContext.transformForFixedPositioned = localContext.currentTransform ;
194 localContext.paintOffsetForFixedPositioned = localContext.paintOffset;
195 }
196
197 // * Memorize the nodes we created for future reference during paint.
198 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newTransformNodeForPerspective || newTransformNodeForScrollTranslation) {
199 ObjectPaintProperties& properties = object.ensureObjectPaintProperties() ;
200 properties.setPaintOffsetTranslation(newTransformNodeForPaintOffsetTrans lation.release());
201 properties.setTransform(newTransformNodeForTransform.release());
202 properties.setPerspective(newTransformNodeForPerspective.release());
203 properties.setScrollTranslation(newTransformNodeForScrollTranslation.rel ease());
204 } else {
205 object.clearObjectPaintProperties();
206 }
207
208 // * Recur.
209
210 // TODO(trchen): Walk subframes for LayoutFrame.
211
212 // TODO(trchen): Implement SVG walk.
213 if (object.isSVGRoot()) {
214 return;
215 }
216
217 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) {
218 if (child->isText())
219 continue;
220 walk(toLayoutBoxModelObject(*child), localContext);
221 }
222 }
223
224 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698