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

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: minor bug fix (perspective does not clear paint offset). switch test to unit test style. add a few … 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 struct PaintPropertyTreeBuilder::Context {
pdr. 2015/10/20 22:02:30 Lets doc this with a small comment describing why
jbroman 2015/10/20 23:50:13 I'd also like a brief explanation of how it works.
trchen 2015/10/21 06:16:20 Done.
18 Context() : currentTransform(nullptr), transformForOutOfFlowPositioned(nullp tr), transformForFixedPositioned(nullptr) { }
19
20 TransformPaintPropertyNode* currentTransform;
21 LayoutPoint paintOffset;
22
23 TransformPaintPropertyNode* transformForOutOfFlowPositioned;
24 LayoutPoint paintOffsetForOutOfFlowPositioned;
25
26 TransformPaintPropertyNode* transformForFixedPositioned;
27 LayoutPoint paintOffsetForFixedPositioned;
28 };
29
30 void PaintPropertyTreeBuilder::buildPropertyTrees(FrameView& rootFrame)
31 {
32 walk(rootFrame, Context());
33 }
34
35 void PaintPropertyTreeBuilder::walk(FrameView& frameView, const Context& context )
36 {
37 Context localContext(context);
38 RefPtr<TransformPaintPropertyNode> newTransformNodeForPreTranslation;
pdr. 2015/10/20 22:02:30 In this function only, lets move these decls down
trchen 2015/10/21 06:16:20 Done.
39 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation;
40
41 TransformationMatrix frameTranslate;
42 frameTranslate.translate(frameView.x(), frameView.y());
43 // The frame owner applies paint offset already.
44 // This assumption may change in the future.
45 ASSERT(context.paintOffset == LayoutPoint());
46 newTransformNodeForPreTranslation = TransformPaintPropertyNode::create(frame Translate, FloatPoint3D(), context.currentTransform);
47 localContext.transformForFixedPositioned = newTransformNodeForPreTranslation .get();
48 localContext.paintOffsetForFixedPositioned = LayoutPoint();
49
50 // This is going away in favor of Settings::rootLayerScrolls.
51 DoubleSize scrollOffset = frameView.scrollOffsetDouble();
52 TransformationMatrix frameScroll;
53 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height());
54 newTransformNodeForScrollTranslation = TransformPaintPropertyNode::create(fr ameScroll, FloatPoint3D(), newTransformNodeForPreTranslation);
55 localContext.currentTransform = localContext.transformForOutOfFlowPositioned = newTransformNodeForScrollTranslation.get();
56 localContext.paintOffset = localContext.paintOffsetForOutOfFlowPositioned = LayoutPoint();
57
58 frameView.setPreTranslation(newTransformNodeForPreTranslation.release());
59 frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release( ));
60
61 if (LayoutView* layoutView = frameView.layoutView())
62 walk(*layoutView, localContext);
63 }
64
65 static bool shouldCreatePreTranslationNode(LayoutBoxModelObject& object)
66 {
67 // TODO(trchen): Eliminate PaintLayer dependency.
68 PaintLayer* layer = object.layer();
69 if (!layer)
70 return false;
71
72 return layer->paintsWithTransform(GlobalPaintNormalPhase);
73 }
74
75 static FloatPoint3D transformOrigin(const LayoutBox& box)
76 {
77 const ComputedStyle& style = box.styleRef();
78
79 FloatSize borderBoxSize(box.size());
80 return FloatPoint3D(floatValueForLength(style.transformOriginX(), borderBoxS ize.width()), floatValueForLength(style.transformOriginY(), borderBoxSize.height ()), style.transformOriginZ());
pdr. 2015/10/20 22:02:30 Can you break this line so it's a little easier to
trchen 2015/10/21 06:16:20 Done.
81 }
82
83 static FloatPoint perspectiveOrigin(const LayoutBox& box)
84 {
85 const ComputedStyle& style = box.styleRef();
86
jbroman 2015/10/20 23:50:13 super-nit: remove this newline?
trchen 2015/10/21 06:16:20 Done.
87 FloatSize borderBoxSize(box.size());
88 return FloatPoint(floatValueForLength(style.perspectiveOriginX(), borderBoxS ize.width()), floatValueForLength(style.perspectiveOriginY(), borderBoxSize.heig ht()));
89 }
90
91 void PaintPropertyTreeBuilder::walk(LayoutBoxModelObject& object, const Context& context)
92 {
93 ASSERT(object.isBox() != object.isLayoutInline()); // Either or.
pdr. 2015/10/20 22:02:30 There are many checks for isBox() in this function
trchen 2015/10/21 06:16:20 Yea... Many CSS properties don't apply on inlines.
94
95 Context localContext(context);
96 RefPtr<TransformPaintPropertyNode> newTransformNodeForPreTranslation;
97 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform;
98 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective;
99 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation;
100
101 // Step 1: Figure out the layout space of the current object.
102 const ComputedStyle& style = object.styleRef();
103 // TODO(trchen): There is some insanity going on with tables. Double check r esults.
104 switch (style.position()) {
105 case StaticPosition:
106 break;
107 case RelativePosition:
108 localContext.paintOffset += object.offsetForInFlowPosition();
109 break;
110 case AbsolutePosition:
111 localContext.currentTransform = context.transformForOutOfFlowPositioned;
112 localContext.paintOffset = context.paintOffsetForOutOfFlowPositioned;
113 break;
114 case StickyPosition:
115 localContext.paintOffset += object.offsetForInFlowPosition();
116 break;
117 case FixedPosition:
118 localContext.currentTransform = context.transformForFixedPositioned;
119 localContext.paintOffset = context.paintOffsetForFixedPositioned;
120 break;
121 default:
122 ASSERT_NOT_REACHED();
123 }
124 if (object.isBox())
125 localContext.paintOffset += toLayoutBox(object).locationOffset();
126
127 // Step 2: Create a transform node to consolidate paint offset (if needed).
128 if (shouldCreatePreTranslationNode(object) && localContext.paintOffset != La youtPoint()) {
129 TransformationMatrix matrix;
130 matrix.translate(localContext.paintOffset.x(), localContext.paintOffset. y());
131 newTransformNodeForPreTranslation = TransformPaintPropertyNode::create(m atrix, FloatPoint3D(), localContext.currentTransform);
132 localContext.currentTransform = newTransformNodeForPreTranslation.get();
133 localContext.paintOffset = LayoutPoint();
134 }
135
136 // Step 3: Create a transform node for CSS transform (if presents).
pdr. 2015/10/20 22:02:30 Nit: "if presents" -> "if present" (here, and belo
trchen 2015/10/21 06:16:20 Done.
137 bool hasTransform = object.isBox() && style.hasTransform();
138 if (hasTransform) {
139 TransformationMatrix matrix;
140 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle:: ExcludeTransformOrigin, ComputedStyle::IncludeMotionPath, ComputedStyle::Include IndependentTransformProperties);
jbroman 2015/10/20 23:50:13 nit: Mind wrapping some of these long lines? I kno
trchen 2015/10/21 06:16:20 Done.
141 newTransformNodeForTransform = TransformPaintPropertyNode::create(matrix , transformOrigin(toLayoutBox(object)), localContext.currentTransform);
142 localContext.currentTransform = newTransformNodeForTransform.get();
143 ASSERT(localContext.paintOffset == LayoutPoint());
144 }
145 // At this point, the current space is the space we paint the element itself .
146
147 // Step 3: Create a transform node for CSS perspective (if presents).
jbroman 2015/10/20 23:50:13 nit: There are two step 3s. I would probably remov
trchen 2015/10/21 06:16:20 Done.
148 if (object.isBox() && style.hasPerspective()) {
149 TransformationMatrix matrix;
150 matrix.applyPerspective(style.perspective());
151 newTransformNodeForPerspective = TransformPaintPropertyNode::create(matr ix, perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(localContext.paintOffs et), localContext.currentTransform);
152 localContext.currentTransform = newTransformNodeForPerspective.get();
153 }
154
155 // Step 4: Create a transform node for overflow clip (if presents).
156 if (object.hasOverflowClip()) {
157 PaintLayer* layer = object.layer();
158 ASSERT(layer);
159 DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset();
160 if (!scrollOffset.isZero() || layer->scrollsOverflow()) {
161 TransformationMatrix matrix;
162 matrix.translate(-scrollOffset.width(), -scrollOffset.height());
163 newTransformNodeForScrollTranslation = TransformPaintPropertyNode::c reate(matrix, FloatPoint3D(), localContext.currentTransform);
164 localContext.currentTransform = newTransformNodeForScrollTranslation .get();
165 }
166 }
167 // At this point, the current space is the space we paint in-flow children.
168
169 // Step 5: Update the context for out-of-flow descendants (if position conta iner is established).
170 if (style.position() != StaticPosition || hasTransform) {
jbroman 2015/10/20 23:50:13 Does the logic for what creates a containing block
trchen 2015/10/21 06:16:20 Nope, any divergence is unintentional. shouldCreat
171 localContext.transformForOutOfFlowPositioned = localContext.currentTrans form;
172 localContext.paintOffsetForOutOfFlowPositioned = localContext.paintOffse t;
173 }
174 if (hasTransform) {
175 localContext.transformForFixedPositioned = localContext.currentTransform ;
176 localContext.paintOffsetForFixedPositioned = localContext.paintOffset;
177 }
178
179 // Step 6: Memorize the nodes we created for future reference during paint.
180 if (newTransformNodeForPreTranslation || newTransformNodeForTransform || new TransformNodeForPerspective || newTransformNodeForScrollTranslation) {
181 ObjectPaintProperties& properties = object.ensureObjectPaintProperties() ;
182 properties.setPreTranslation(newTransformNodeForPreTranslation.release() );
183 properties.setTransform(newTransformNodeForTransform.release());
184 properties.setPerspective(newTransformNodeForPerspective.release());
185 properties.setScrollTranslation(newTransformNodeForScrollTranslation.rel ease());
186 } else {
187 object.clearObjectPaintProperties();
188 }
189
190 // Step 7: Recur.
191 if (object.isSVGRoot()) {
pdr. 2015/10/20 22:02:30 Nit: // TODO(trchen): Implement the SVG transform
trchen 2015/10/21 06:16:20 Done.
192 // TODO(trchen): Implement SVG walk.
193 return;
194 }
195
196 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) {
pdr. 2015/10/20 22:02:30 Lets move the recur comment here.
trchen 2015/10/21 06:16:20 Nah, for SVG walk it is going to recur too. Just t
197 if (child->isText())
198 continue;
199 walk(toLayoutBoxModelObject(*child), localContext);
200 }
201 }
202
203 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698