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

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

Issue 2456113002: Separate property and context updates in PaintPropertyTreeBuilder (Closed)
Patch Set: Cleanup names/comments, fix preserves3d bug Created 4 years, 1 month 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/paint/PaintPropertyTreeBuilder.h" 5 #include "core/paint/PaintPropertyTreeBuilder.h"
6 6
7 #include "core/frame/FrameView.h" 7 #include "core/frame/FrameView.h"
8 #include "core/frame/LocalFrame.h" 8 #include "core/frame/LocalFrame.h"
9 #include "core/frame/Settings.h" 9 #include "core/frame/Settings.h"
10 #include "core/layout/LayoutInline.h" 10 #include "core/layout/LayoutInline.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 context.current.scroll = context.absolutePosition.scroll = 65 context.current.scroll = context.absolutePosition.scroll =
66 context.fixedPosition.scroll = rootScrollNode(); 66 context.fixedPosition.scroll = rootScrollNode();
67 67
68 // Ensure scroll tree properties are reset. They will be rebuilt during the 68 // Ensure scroll tree properties are reset. They will be rebuilt during the
69 // tree walk. 69 // tree walk.
70 rootScrollNode()->clearMainThreadScrollingReasons(); 70 rootScrollNode()->clearMainThreadScrollingReasons();
71 71
72 return context; 72 return context;
73 } 73 }
74 74
75 const TransformPaintPropertyNode* updateFrameViewPreTranslation( 75 void updateFrameViewPreTranslation(
76 FrameView& frameView, 76 FrameView& frameView,
77 PassRefPtr<const TransformPaintPropertyNode> parent, 77 PassRefPtr<const TransformPaintPropertyNode> parent,
78 const TransformationMatrix& matrix, 78 const TransformationMatrix& matrix,
79 const FloatPoint3D& origin) { 79 const FloatPoint3D& origin) {
80 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); 80 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled());
81 if (TransformPaintPropertyNode* existingPreTranslation = 81 if (auto* existingPreTranslation = frameView.preTranslation()) {
82 frameView.preTranslation())
83 existingPreTranslation->update(std::move(parent), matrix, origin); 82 existingPreTranslation->update(std::move(parent), matrix, origin);
84 else 83 } else {
85 frameView.setPreTranslation( 84 frameView.setPreTranslation(
86 TransformPaintPropertyNode::create(std::move(parent), matrix, origin)); 85 TransformPaintPropertyNode::create(std::move(parent), matrix, origin));
87 return frameView.preTranslation(); 86 }
88 } 87 }
89 88
90 const ClipPaintPropertyNode* updateFrameViewContentClip( 89 void updateFrameViewContentClip(
91 FrameView& frameView, 90 FrameView& frameView,
92 PassRefPtr<const ClipPaintPropertyNode> parent, 91 PassRefPtr<const ClipPaintPropertyNode> parent,
93 PassRefPtr<const TransformPaintPropertyNode> localTransformSpace, 92 PassRefPtr<const TransformPaintPropertyNode> localTransformSpace,
94 const FloatRoundedRect& clipRect) { 93 const FloatRoundedRect& clipRect) {
95 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); 94 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled());
96 if (ClipPaintPropertyNode* existingContentClip = frameView.contentClip()) 95 if (auto* existingContentClip = frameView.contentClip()) {
97 existingContentClip->update(std::move(parent), 96 existingContentClip->update(std::move(parent),
98 std::move(localTransformSpace), clipRect); 97 std::move(localTransformSpace), clipRect);
99 else 98 } else {
100 frameView.setContentClip(ClipPaintPropertyNode::create( 99 frameView.setContentClip(ClipPaintPropertyNode::create(
101 std::move(parent), std::move(localTransformSpace), clipRect)); 100 std::move(parent), std::move(localTransformSpace), clipRect));
102 return frameView.contentClip(); 101 }
103 } 102 }
104 103
105 const TransformPaintPropertyNode* updateFrameViewScrollTranslation( 104 void updateFrameViewScrollTranslation(
106 FrameView& frameView, 105 FrameView& frameView,
107 PassRefPtr<const TransformPaintPropertyNode> parent, 106 PassRefPtr<const TransformPaintPropertyNode> parent,
108 const TransformationMatrix& matrix, 107 const TransformationMatrix& matrix,
109 const FloatPoint3D& origin) { 108 const FloatPoint3D& origin) {
110 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); 109 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled());
111 if (TransformPaintPropertyNode* existingScrollTranslation = 110 if (auto* existingScrollTranslation = frameView.scrollTranslation()) {
112 frameView.scrollTranslation())
113 existingScrollTranslation->update(std::move(parent), matrix, origin); 111 existingScrollTranslation->update(std::move(parent), matrix, origin);
114 else 112 } else {
115 frameView.setScrollTranslation( 113 frameView.setScrollTranslation(
116 TransformPaintPropertyNode::create(std::move(parent), matrix, origin)); 114 TransformPaintPropertyNode::create(std::move(parent), matrix, origin));
117 return frameView.scrollTranslation(); 115 }
118 } 116 }
119 117
120 ScrollPaintPropertyNode* updateFrameViewScroll( 118 void updateFrameViewScroll(
121 FrameView& frameView, 119 FrameView& frameView,
122 PassRefPtr<ScrollPaintPropertyNode> parent, 120 PassRefPtr<ScrollPaintPropertyNode> parent,
123 PassRefPtr<const TransformPaintPropertyNode> scrollOffset, 121 PassRefPtr<const TransformPaintPropertyNode> scrollOffset,
124 const IntSize& clip, 122 const IntSize& clip,
125 const IntSize& bounds, 123 const IntSize& bounds,
126 bool userScrollableHorizontal, 124 bool userScrollableHorizontal,
127 bool userScrollableVertical) { 125 bool userScrollableVertical) {
128 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); 126 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled());
129 if (ScrollPaintPropertyNode* existingScroll = frameView.scroll()) 127 if (auto* existingScroll = frameView.scroll()) {
130 existingScroll->update(std::move(parent), std::move(scrollOffset), clip, 128 existingScroll->update(std::move(parent), std::move(scrollOffset), clip,
131 bounds, userScrollableHorizontal, 129 bounds, userScrollableHorizontal,
132 userScrollableVertical); 130 userScrollableVertical);
133 else 131 } else {
134 frameView.setScroll(ScrollPaintPropertyNode::create( 132 frameView.setScroll(ScrollPaintPropertyNode::create(
135 std::move(parent), std::move(scrollOffset), clip, bounds, 133 std::move(parent), std::move(scrollOffset), clip, bounds,
136 userScrollableHorizontal, userScrollableVertical)); 134 userScrollableHorizontal, userScrollableVertical));
137 return frameView.scroll(); 135 }
138 } 136 }
139 137
140 void PaintPropertyTreeBuilder::buildTreeNodes( 138 void PaintPropertyTreeBuilder::updatePropertiesAndContext(
141 FrameView& frameView, 139 FrameView& frameView,
142 PaintPropertyTreeBuilderContext& context) { 140 PaintPropertyTreeBuilderContext& context) {
143 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { 141 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
144 LayoutView* layoutView = frameView.layoutView(); 142 LayoutView* layoutView = frameView.layoutView();
145 if (!layoutView) 143 if (!layoutView)
146 return; 144 return;
147 145
148 TransformationMatrix frameTranslate; 146 TransformationMatrix frameTranslate;
149 frameTranslate.translate(frameView.x() + layoutView->location().x() + 147 frameTranslate.translate(frameView.x() + layoutView->location().x() +
150 context.current.paintOffset.x(), 148 context.current.paintOffset.x(),
151 frameView.y() + layoutView->location().y() + 149 frameView.y() + layoutView->location().y() +
152 context.current.paintOffset.y()); 150 context.current.paintOffset.y());
153 context.current.transform = 151 layoutView->getMutableForPainting()
154 layoutView->getMutableForPainting() 152 .ensurePaintProperties()
155 .ensurePaintProperties() 153 .updatePaintOffsetTranslation(context.current.transform, frameTranslate,
156 .updatePaintOffsetTranslation(context.current.transform, 154 FloatPoint3D());
157 frameTranslate, FloatPoint3D()); 155
156 const auto* properties = layoutView->paintProperties();
157 DCHECK(properties && properties->paintOffsetTranslation());
158 context.current.transform = properties->paintOffsetTranslation();
158 context.current.paintOffset = LayoutPoint(); 159 context.current.paintOffset = LayoutPoint();
159 context.current.renderingContextID = 0; 160 context.current.renderingContextID = 0;
160 context.current.shouldFlattenInheritedTransform = true; 161 context.current.shouldFlattenInheritedTransform = true;
161 context.absolutePosition = context.current; 162 context.absolutePosition = context.current;
162 context.containerForAbsolutePosition = 163 context.containerForAbsolutePosition =
163 nullptr; // This will get set in updateOutOfFlowContext(). 164 nullptr; // This will get set in updateOutOfFlowContext().
164 context.fixedPosition = context.current; 165 context.fixedPosition = context.current;
165 return; 166 return;
166 } 167 }
167 168
168 TransformationMatrix frameTranslate; 169 TransformationMatrix frameTranslate;
169 frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), 170 frameTranslate.translate(frameView.x() + context.current.paintOffset.x(),
170 frameView.y() + context.current.paintOffset.y()); 171 frameView.y() + context.current.paintOffset.y());
171 context.current.transform = updateFrameViewPreTranslation( 172 updateFrameViewPreTranslation(frameView, context.current.transform,
172 frameView, context.current.transform, frameTranslate, FloatPoint3D()); 173 frameTranslate, FloatPoint3D());
173 174
174 FloatRoundedRect contentClip( 175 FloatRoundedRect contentClip(
175 IntRect(IntPoint(), frameView.visibleContentSize())); 176 IntRect(IntPoint(), frameView.visibleContentSize()));
176 context.current.clip = updateFrameViewContentClip( 177 updateFrameViewContentClip(frameView, context.current.clip,
177 frameView, context.current.clip, frameView.preTranslation(), contentClip); 178 frameView.preTranslation(), contentClip);
178
179 // Record the fixed properties before any scrolling occurs.
180 const auto* fixedTransformNode = context.current.transform;
181 auto* fixedScrollNode = context.current.scroll;
182 179
183 ScrollOffset scrollOffset = frameView.scrollOffset(); 180 ScrollOffset scrollOffset = frameView.scrollOffset();
184 if (frameView.isScrollable() || !scrollOffset.isZero()) { 181 if (frameView.isScrollable() || !scrollOffset.isZero()) {
185 TransformationMatrix frameScroll; 182 TransformationMatrix frameScroll;
186 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); 183 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height());
187 context.current.transform = updateFrameViewScrollTranslation( 184 updateFrameViewScrollTranslation(frameView, frameView.preTranslation(),
188 frameView, frameView.preTranslation(), frameScroll, FloatPoint3D()); 185 frameScroll, FloatPoint3D());
189 186
190 IntSize scrollClip = frameView.visibleContentSize(); 187 IntSize scrollClip = frameView.visibleContentSize();
191 IntSize scrollBounds = frameView.contentsSize(); 188 IntSize scrollBounds = frameView.contentsSize();
192 bool userScrollableHorizontal = 189 bool userScrollableHorizontal =
193 frameView.userInputScrollable(HorizontalScrollbar); 190 frameView.userInputScrollable(HorizontalScrollbar);
194 bool userScrollableVertical = 191 bool userScrollableVertical =
195 frameView.userInputScrollable(VerticalScrollbar); 192 frameView.userInputScrollable(VerticalScrollbar);
196 context.current.scroll = updateFrameViewScroll( 193 updateFrameViewScroll(frameView, context.current.scroll,
197 frameView, context.current.scroll, frameView.scrollTranslation(), 194 frameView.scrollTranslation(), scrollClip,
198 scrollClip, scrollBounds, userScrollableHorizontal, 195 scrollBounds, userScrollableHorizontal,
199 userScrollableVertical); 196 userScrollableVertical);
200 } else { 197 } else {
201 // Ensure pre-existing properties are cleared when there is no scrolling. 198 // Ensure pre-existing properties are cleared when there is no scrolling.
202 frameView.setScrollTranslation(nullptr); 199 frameView.setScrollTranslation(nullptr);
203 frameView.setScroll(nullptr); 200 frameView.setScroll(nullptr);
204 } 201 }
205 202
206 // Initialize the context for current, absolute and fixed position cases. 203 // Initialize the context for current, absolute and fixed position cases.
207 // They are the same, except that scroll translation does not apply to 204 // They are the same, except that scroll translation does not apply to
208 // fixed position descendants. 205 // fixed position descendants.
206 const auto* fixedTransformNode = frameView.preTranslation()
207 ? frameView.preTranslation()
208 : context.current.transform;
209 auto* fixedScrollNode = context.current.scroll;
210 DCHECK(frameView.preTranslation());
211 context.current.transform = frameView.preTranslation();
212 DCHECK(frameView.contentClip());
213 context.current.clip = frameView.contentClip();
214 if (const auto* scrollTranslation = frameView.scrollTranslation())
215 context.current.transform = scrollTranslation;
216 if (auto* scroll = frameView.scroll())
217 context.current.scroll = scroll;
209 context.current.paintOffset = LayoutPoint(); 218 context.current.paintOffset = LayoutPoint();
210 context.current.renderingContextID = 0; 219 context.current.renderingContextID = 0;
211 context.current.shouldFlattenInheritedTransform = true; 220 context.current.shouldFlattenInheritedTransform = true;
212 context.absolutePosition = context.current; 221 context.absolutePosition = context.current;
213 context.containerForAbsolutePosition = nullptr; 222 context.containerForAbsolutePosition = nullptr;
214 context.fixedPosition = context.current; 223 context.fixedPosition = context.current;
215 context.fixedPosition.transform = fixedTransformNode; 224 context.fixedPosition.transform = fixedTransformNode;
216 context.fixedPosition.scroll = fixedScrollNode; 225 context.fixedPosition.scroll = fixedScrollNode;
217 226
218 std::unique_ptr<PropertyTreeState> contentsState( 227 std::unique_ptr<PropertyTreeState> contentsState(
219 new PropertyTreeState(context.current.transform, context.current.clip, 228 new PropertyTreeState(context.current.transform, context.current.clip,
220 context.currentEffect, context.current.scroll)); 229 context.currentEffect, context.current.scroll));
221 frameView.setTotalPropertyTreeStateForContents(std::move(contentsState)); 230 frameView.setTotalPropertyTreeStateForContents(std::move(contentsState));
222 } 231 }
223 232
224 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation( 233 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(
225 const LayoutObject& object, 234 const LayoutObject& object,
226 PaintPropertyTreeBuilderContext& context) { 235 PaintPropertyTreeBuilderContext& context) {
227 // LayoutView's paint offset is updated in the FrameView property update. 236 // LayoutView's paint offset is updated in the FrameView property update.
228 if (object.isLayoutView()) { 237 if (object.isLayoutView()) {
229 DCHECK(context.current.paintOffset == LayoutPoint()); 238 DCHECK(context.current.paintOffset == LayoutPoint());
230 return; 239 return;
231 } 240 }
232 241
242 bool usesPaintOffsetTranslation = false;
233 if (object.isBoxModelObject() && 243 if (object.isBoxModelObject() &&
234 context.current.paintOffset != LayoutPoint()) { 244 context.current.paintOffset != LayoutPoint()) {
235 // TODO(trchen): Eliminate PaintLayer dependency. 245 // TODO(trchen): Eliminate PaintLayer dependency.
236 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); 246 PaintLayer* layer = toLayoutBoxModelObject(object).layer();
237 if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) { 247 if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase))
238 // We should use the same subpixel paint offset values for snapping 248 usesPaintOffsetTranslation = true;
239 // regardless of whether a transform is present. If there is a transform
240 // we round the paint offset but keep around the residual fractional
241 // component for the transformed content to paint with. In spv1 this was
242 // called "subpixel accumulation". For more information, see
243 // PaintLayer::subpixelAccumulation() and
244 // PaintLayerPainter::paintFragmentByApplyingTransform.
245 IntPoint roundedPaintOffset =
246 roundedIntPoint(context.current.paintOffset);
247 LayoutPoint fractionalPaintOffset =
248 LayoutPoint(context.current.paintOffset - roundedPaintOffset);
249
250 context.current.transform =
251 object.getMutableForPainting()
252 .ensurePaintProperties()
253 .updatePaintOffsetTranslation(
254 context.current.transform,
255 TransformationMatrix().translate(roundedPaintOffset.x(),
256 roundedPaintOffset.y()),
257 FloatPoint3D(),
258 context.current.shouldFlattenInheritedTransform,
259 context.current.renderingContextID);
260 context.current.paintOffset = fractionalPaintOffset;
261 return;
262 }
263 } 249 }
264 250
265 if (auto* properties = object.getMutableForPainting().paintProperties()) 251 // We should use the same subpixel paint offset values for snapping
266 properties->clearPaintOffsetTranslation(); 252 // regardless of whether a transform is present. If there is a transform
253 // we round the paint offset but keep around the residual fractional
254 // component for the transformed content to paint with. In spv1 this was
255 // called "subpixel accumulation". For more information, see
256 // PaintLayer::subpixelAccumulation() and
257 // PaintLayerPainter::paintFragmentByApplyingTransform.
258 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset);
259 LayoutPoint fractionalPaintOffset =
260 LayoutPoint(context.current.paintOffset - roundedPaintOffset);
261
262 if (usesPaintOffsetTranslation) {
263 object.getMutableForPainting()
264 .ensurePaintProperties()
265 .updatePaintOffsetTranslation(
266 context.current.transform,
267 TransformationMatrix().translate(roundedPaintOffset.x(),
268 roundedPaintOffset.y()),
269 FloatPoint3D(), context.current.shouldFlattenInheritedTransform,
270 context.current.renderingContextID);
271 } else {
272 if (auto* properties = object.getMutableForPainting().paintProperties())
273 properties->clearPaintOffsetTranslation();
274 }
275
276 const auto* properties = object.paintProperties();
277 if (properties && properties->paintOffsetTranslation()) {
278 context.current.transform = properties->paintOffsetTranslation();
279 context.current.paintOffset = fractionalPaintOffset;
280 }
267 } 281 }
268 282
269 static FloatPoint3D transformOrigin(const LayoutBox& box) { 283 static FloatPoint3D transformOrigin(const LayoutBox& box) {
270 const ComputedStyle& style = box.styleRef(); 284 const ComputedStyle& style = box.styleRef();
271 FloatSize borderBoxSize(box.size()); 285 FloatSize borderBoxSize(box.size());
272 return FloatPoint3D( 286 return FloatPoint3D(
273 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), 287 floatValueForLength(style.transformOriginX(), borderBoxSize.width()),
274 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), 288 floatValueForLength(style.transformOriginY(), borderBoxSize.height()),
275 style.transformOriginZ()); 289 style.transformOriginZ());
276 } 290 }
277 291
278 // SVG does not use the general transform update of |updateTransform|, instead 292 // SVG does not use the general transform update of |updateTransform|, instead
279 // creating a transform node for SVG-specific transforms without 3D. 293 // creating a transform node for SVG-specific transforms without 3D.
280 void PaintPropertyTreeBuilder::updateTransformForNonRootSVG( 294 void PaintPropertyTreeBuilder::updateTransformForNonRootSVG(
281 const LayoutObject& object, 295 const LayoutObject& object,
282 PaintPropertyTreeBuilderContext& context) { 296 PaintPropertyTreeBuilderContext& context) {
283 DCHECK(object.isSVG() && !object.isSVGRoot()); 297 DCHECK(object.isSVG() && !object.isSVGRoot());
284 // SVG (other than SVGForeignObject) does not use paint offset internally. 298 // SVG (other than SVGForeignObject) does not use paint offset internally.
285 DCHECK(object.isSVGForeignObject() || 299 DCHECK(object.isSVGForeignObject() ||
286 context.current.paintOffset == LayoutPoint()); 300 context.current.paintOffset == LayoutPoint());
287 301
288 // FIXME(pdr): Refactor this so all non-root SVG objects use the same 302 // TODO(pdr): Refactor this so all non-root SVG objects use the same
289 // transform function. 303 // transform function.
290 const AffineTransform& transform = object.isSVGForeignObject() 304 const AffineTransform& transform = object.isSVGForeignObject()
291 ? object.localSVGTransform() 305 ? object.localSVGTransform()
292 : object.localToSVGParentTransform(); 306 : object.localToSVGParentTransform();
293 307 // TODO(pdr): Check for the presence of a transform instead of the value.
294 // FIXME(pdr): Check for the presence of a transform instead of the value. 308 // Checking for an identity matrix will cause the property tree structure
295 // Checking for an identity matrix will cause the property tree structure to 309 // to change during animations if the animation passes through the
296 // change during animations if the animation passes through the identity 310 // identity matrix.
297 // matrix.
298 if (!transform.isIdentity()) { 311 if (!transform.isIdentity()) {
299 // The origin is included in the local transform, so leave origin empty. 312 // The origin is included in the local transform, so leave origin empty.
300 context.current.transform = 313 object.getMutableForPainting().ensurePaintProperties().updateTransform(
301 object.getMutableForPainting().ensurePaintProperties().updateTransform( 314 context.current.transform, TransformationMatrix(transform),
302 context.current.transform, TransformationMatrix(transform), 315 FloatPoint3D());
303 FloatPoint3D());
304 context.current.renderingContextID = 0;
305 context.current.shouldFlattenInheritedTransform = false;
306 } else { 316 } else {
307 if (auto* properties = object.getMutableForPainting().paintProperties()) 317 if (auto* properties = object.getMutableForPainting().paintProperties())
308 properties->clearTransform(); 318 properties->clearTransform();
309 } 319 }
320
321 if (object.paintProperties() && object.paintProperties()->transform()) {
322 context.current.transform = object.paintProperties()->transform();
323 context.current.shouldFlattenInheritedTransform = false;
324 context.current.renderingContextID = 0;
325 }
310 } 326 }
311 327
312 void PaintPropertyTreeBuilder::updateTransform( 328 void PaintPropertyTreeBuilder::updateTransform(
313 const LayoutObject& object, 329 const LayoutObject& object,
314 PaintPropertyTreeBuilderContext& context) { 330 PaintPropertyTreeBuilderContext& context) {
315 if (object.isSVG() && !object.isSVGRoot()) { 331 if (object.isSVG() && !object.isSVGRoot()) {
316 updateTransformForNonRootSVG(object, context); 332 updateTransformForNonRootSVG(object, context);
317 return; 333 return;
318 } 334 }
319 335
320 const ComputedStyle& style = object.styleRef(); 336 const ComputedStyle& style = object.styleRef();
321 if (object.isBox() && (style.hasTransform() || style.preserves3D())) { 337 if (object.isBox() && (style.hasTransform() || style.preserves3D())) {
322 TransformationMatrix matrix; 338 TransformationMatrix matrix;
323 style.applyTransform(matrix, toLayoutBox(object).size(), 339 style.applyTransform(matrix, toLayoutBox(object).size(),
324 ComputedStyle::ExcludeTransformOrigin, 340 ComputedStyle::ExcludeTransformOrigin,
325 ComputedStyle::IncludeMotionPath, 341 ComputedStyle::IncludeMotionPath,
326 ComputedStyle::IncludeIndependentTransformProperties); 342 ComputedStyle::IncludeIndependentTransformProperties);
327 FloatPoint3D origin = transformOrigin(toLayoutBox(object));
328
329 unsigned renderingContextID = context.current.renderingContextID;
330 unsigned renderingContextIDForChildren = 0;
331 bool flattensInheritedTransform =
332 context.current.shouldFlattenInheritedTransform;
333 bool childrenFlattenInheritedTransform = true;
334 343
335 // TODO(trchen): transform-style should only be respected if a PaintLayer 344 // TODO(trchen): transform-style should only be respected if a PaintLayer
336 // is created. 345 // is created.
337 if (style.preserves3D()) { 346 // If a node with transform-style: preserve-3d does not exist in an
338 // If a node with transform-style: preserve-3d does not exist in an 347 // existing rendering context, it establishes a new one.
339 // existing rendering context, it establishes a new one. 348 unsigned renderingContextID = context.current.renderingContextID;
340 if (!renderingContextID) 349 if (style.preserves3D() && !renderingContextID)
341 renderingContextID = PtrHash<const LayoutObject>::hash(&object); 350 renderingContextID = PtrHash<const LayoutObject>::hash(&object);
342 renderingContextIDForChildren = renderingContextID;
343 childrenFlattenInheritedTransform = false;
344 }
345 351
346 context.current.transform = 352 object.getMutableForPainting().ensurePaintProperties().updateTransform(
347 object.getMutableForPainting().ensurePaintProperties().updateTransform( 353 context.current.transform, matrix, transformOrigin(toLayoutBox(object)),
348 context.current.transform, matrix, origin, 354 context.current.shouldFlattenInheritedTransform, renderingContextID);
349 flattensInheritedTransform, renderingContextID);
350 context.current.renderingContextID = renderingContextIDForChildren;
351 context.current.shouldFlattenInheritedTransform =
352 childrenFlattenInheritedTransform;
353 } else { 355 } else {
354 if (auto* properties = object.getMutableForPainting().paintProperties()) 356 if (auto* properties = object.getMutableForPainting().paintProperties())
355 properties->clearTransform(); 357 properties->clearTransform();
356 } 358 }
359
360 const auto* properties = object.paintProperties();
361 if (properties && properties->transform()) {
362 context.current.transform = properties->transform();
363 if (object.styleRef().preserves3D()) {
364 context.current.renderingContextID =
365 properties->transform()->renderingContextID();
366 context.current.shouldFlattenInheritedTransform = false;
367 } else {
368 context.current.renderingContextID = 0;
369 context.current.shouldFlattenInheritedTransform = true;
370 }
371 }
357 } 372 }
358 373
359 void PaintPropertyTreeBuilder::updateEffect( 374 void PaintPropertyTreeBuilder::updateEffect(
360 const LayoutObject& object, 375 const LayoutObject& object,
361 PaintPropertyTreeBuilderContext& context) { 376 PaintPropertyTreeBuilderContext& context) {
362 const ComputedStyle& style = object.styleRef(); 377 const ComputedStyle& style = object.styleRef();
363 378
364 if (!style.isStackingContext()) { 379 if (!style.isStackingContext()) {
365 if (ObjectPaintProperties* properties = 380 if (auto* properties = object.getMutableForPainting().paintProperties())
366 object.getMutableForPainting().paintProperties())
367 properties->clearEffect(); 381 properties->clearEffect();
368 return; 382 return;
369 } 383 }
370 384
371 // TODO(trchen): Can't omit effect node if we have 3D children. 385 // TODO(trchen): Can't omit effect node if we have 3D children.
372 // TODO(trchen): Can't omit effect node if we have blending children. 386 // TODO(trchen): Can't omit effect node if we have blending children.
373 bool effectNodeNeeded = false; 387 bool effectNodeNeeded = false;
374 388
375 float opacity = style.opacity(); 389 float opacity = style.opacity();
376 if (opacity != 1.0f) 390 if (opacity != 1.0f)
(...skipping 23 matching lines...) Expand all
400 // In this example "A" should be clipped if the filter was not present. 414 // In this example "A" should be clipped if the filter was not present.
401 // With the filter, "A" will be rastered without clipping, but instead 415 // With the filter, "A" will be rastered without clipping, but instead
402 // the blurred result will be clipped. 416 // the blurred result will be clipped.
403 // On the other hand, "B" should not be clipped because the overflow clip is 417 // On the other hand, "B" should not be clipped because the overflow clip is
404 // not in its containing block chain, but as the filter output will be 418 // not in its containing block chain, but as the filter output will be
405 // clipped, so a blurred "B" may still be invisible. 419 // clipped, so a blurred "B" may still be invisible.
406 if (!filter.isEmpty()) { 420 if (!filter.isEmpty()) {
407 effectNodeNeeded = true; 421 effectNodeNeeded = true;
408 outputClip = context.current.clip; 422 outputClip = context.current.clip;
409 423
410 // TODO(trchen): A filter may contain spatial operations such that an output 424 // TODO(trchen): A filter may contain spatial operations such that an
411 // pixel may depend on an input pixel outside of the output clip. Need to 425 // output pixel may depend on an input pixel outside of the output clip.
412 // generate special clip node to hint how to expand clip / cull rect. 426 // We should generate a special clip node to represent this expansion.
427 }
428
429 if (effectNodeNeeded) {
430 object.getMutableForPainting().ensurePaintProperties().updateEffect(
431 context.currentEffect, context.current.transform, outputClip,
432 std::move(filter), opacity);
433 } else {
434 if (auto* properties = object.getMutableForPainting().paintProperties())
435 properties->clearEffect();
436 }
437
438 const auto* properties = object.paintProperties();
439 if (properties && properties->effect()) {
440 context.currentEffect = properties->effect();
441 // TODO(pdr): Once the expansion clip node is created above, it should be
442 // used here to update all current clip nodes;
413 const ClipPaintPropertyNode* expansionHint = context.current.clip; 443 const ClipPaintPropertyNode* expansionHint = context.current.clip;
414 context.current.clip = context.absolutePosition.clip = 444 context.current.clip = context.absolutePosition.clip =
415 context.fixedPosition.clip = expansionHint; 445 context.fixedPosition.clip = expansionHint;
416 } 446 }
417
418 if (!effectNodeNeeded) {
419 if (ObjectPaintProperties* properties =
420 object.getMutableForPainting().paintProperties())
421 properties->clearEffect();
422 return;
423 }
424
425 context.currentEffect =
426 object.getMutableForPainting().ensurePaintProperties().updateEffect(
427 context.currentEffect, context.current.transform, outputClip,
428 std::move(filter), opacity);
429 } 447 }
430 448
431 void PaintPropertyTreeBuilder::updateCssClip( 449 void PaintPropertyTreeBuilder::updateCssClip(
432 const LayoutObject& object, 450 const LayoutObject& object,
433 PaintPropertyTreeBuilderContext& context) { 451 PaintPropertyTreeBuilderContext& context) {
434 if (object.hasClip()) { 452 if (object.hasClip()) {
435 // Create clip node for descendants that are not fixed position. 453 // Create clip node for descendants that are not fixed position.
436 // We don't have to setup context.absolutePosition.clip here because this 454 // We don't have to setup context.absolutePosition.clip here because this
437 // object must be a container for absolute position descendants, and will 455 // object must be a container for absolute position descendants, and will
438 // copy from in-flow context later at updateOutOfFlowContext() step. 456 // copy from in-flow context later at updateOutOfFlowContext() step.
439 DCHECK(object.canContainAbsolutePositionObjects()); 457 DCHECK(object.canContainAbsolutePositionObjects());
440 LayoutRect clipRect = 458 LayoutRect clipRect =
441 toLayoutBox(object).clipRect(context.current.paintOffset); 459 toLayoutBox(object).clipRect(context.current.paintOffset);
442 context.current.clip = 460 object.getMutableForPainting().ensurePaintProperties().updateCssClip(
443 object.getMutableForPainting().ensurePaintProperties().updateCssClip( 461 context.current.clip, context.current.transform,
444 context.current.clip, context.current.transform, 462 FloatRoundedRect(FloatRect(clipRect)));
445 FloatRoundedRect(FloatRect(clipRect))); 463 } else {
446 return; 464 if (auto* properties = object.getMutableForPainting().paintProperties())
465 properties->clearCssClip();
447 } 466 }
448 467
449 if (auto* properties = object.getMutableForPainting().paintProperties()) 468 const auto* properties = object.paintProperties();
450 properties->clearCssClip(); 469 if (properties && properties->cssClip())
470 context.current.clip = properties->cssClip();
451 } 471 }
452 472
453 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext( 473 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(
454 const LayoutObject& object, 474 const LayoutObject& object,
455 PaintPropertyTreeBuilderContext& context) { 475 PaintPropertyTreeBuilderContext& context) {
456 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since 476 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since
457 // we don't need them at the moment. 477 // we don't need them at the moment.
458 if (!object.isBox() && !object.hasLayer()) 478 if (!object.isBox() && !object.hasLayer()) {
459 return; 479 if (auto* properties = object.getMutableForPainting().paintProperties())
460 480 properties->clearLocalBorderBoxProperties();
461 std::unique_ptr<ObjectPaintProperties::PropertyTreeStateWithOffset> 481 } else {
462 borderBoxContext = 482 std::unique_ptr<ObjectPaintProperties::PropertyTreeStateWithOffset>
463 wrapUnique(new ObjectPaintProperties::PropertyTreeStateWithOffset( 483 borderBoxContext =
464 context.current.paintOffset, 484 wrapUnique(new ObjectPaintProperties::PropertyTreeStateWithOffset(
465 PropertyTreeState(context.current.transform, context.current.clip, 485 context.current.paintOffset,
466 context.currentEffect, 486 PropertyTreeState(context.current.transform,
467 context.current.scroll))); 487 context.current.clip, context.currentEffect,
468 object.getMutableForPainting() 488 context.current.scroll)));
469 .ensurePaintProperties() 489 object.getMutableForPainting()
470 .setLocalBorderBoxProperties(std::move(borderBoxContext)); 490 .ensurePaintProperties()
491 .setLocalBorderBoxProperties(std::move(borderBoxContext));
492 }
471 } 493 }
472 494
473 // TODO(trchen): Remove this once we bake the paint offset into frameRect. 495 // TODO(trchen): Remove this once we bake the paint offset into frameRect.
474 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset( 496 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(
475 const LayoutObject& object, 497 const LayoutObject& object,
476 const PaintPropertyTreeBuilderContext& context) { 498 const PaintPropertyTreeBuilderContext& context) {
499 bool needsScrollbarPaintOffset = false;
477 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); 500 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset);
478 if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) { 501 if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) {
479 if (PaintLayerScrollableArea* scrollableArea = 502 if (auto* area = toLayoutBoxModelObject(object).getScrollableArea()) {
480 toLayoutBoxModelObject(object).getScrollableArea()) { 503 if (area->horizontalScrollbar() || area->verticalScrollbar()) {
481 if (scrollableArea->horizontalScrollbar() ||
482 scrollableArea->verticalScrollbar()) {
483 auto paintOffset = TransformationMatrix().translate( 504 auto paintOffset = TransformationMatrix().translate(
484 roundedPaintOffset.x(), roundedPaintOffset.y()); 505 roundedPaintOffset.x(), roundedPaintOffset.y());
485 object.getMutableForPainting() 506 object.getMutableForPainting()
486 .ensurePaintProperties() 507 .ensurePaintProperties()
487 .updateScrollbarPaintOffset(context.current.transform, paintOffset, 508 .updateScrollbarPaintOffset(context.current.transform, paintOffset,
488 FloatPoint3D()); 509 FloatPoint3D());
489 return; 510 needsScrollbarPaintOffset = true;
490 } 511 }
491 } 512 }
492 } 513 }
493 514
494 if (auto* properties = object.getMutableForPainting().paintProperties()) 515 auto* properties = object.getMutableForPainting().paintProperties();
516 if (!needsScrollbarPaintOffset && properties)
495 properties->clearScrollbarPaintOffset(); 517 properties->clearScrollbarPaintOffset();
496 } 518 }
497 519
498 void PaintPropertyTreeBuilder::updateMainThreadScrollingReasons( 520 void PaintPropertyTreeBuilder::updateMainThreadScrollingReasons(
499 const LayoutObject& object, 521 const LayoutObject& object,
500 PaintPropertyTreeBuilderContext& context) { 522 PaintPropertyTreeBuilderContext& context) {
501 if (context.current.scroll && 523 if (context.current.scroll &&
502 !object.document().settings()->threadedScrollingEnabled()) 524 !object.document().settings()->threadedScrollingEnabled()) {
503 context.current.scroll->addMainThreadScrollingReasons( 525 context.current.scroll->addMainThreadScrollingReasons(
504 MainThreadScrollingReason::kThreadedScrollingDisabled); 526 MainThreadScrollingReason::kThreadedScrollingDisabled);
527 }
505 528
506 if (object.isBackgroundAttachmentFixedObject()) { 529 if (object.isBackgroundAttachmentFixedObject()) {
507 auto* scrollNode = context.current.scroll; 530 auto* scrollNode = context.current.scroll;
508 while ( 531 while (
509 scrollNode && 532 scrollNode &&
510 !scrollNode->hasMainThreadScrollingReasons( 533 !scrollNode->hasMainThreadScrollingReasons(
511 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects)) { 534 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects)) {
512 scrollNode->addMainThreadScrollingReasons( 535 scrollNode->addMainThreadScrollingReasons(
513 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); 536 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
514 scrollNode = scrollNode->parent(); 537 scrollNode = scrollNode->parent();
515 } 538 }
516 } 539 }
517 } 540 }
518 541
519 void PaintPropertyTreeBuilder::updateOverflowClip( 542 void PaintPropertyTreeBuilder::updateOverflowClip(
520 const LayoutObject& object, 543 const LayoutObject& object,
521 PaintPropertyTreeBuilderContext& context) { 544 PaintPropertyTreeBuilderContext& context) {
522 if (!object.isBox()) 545 if (!object.isBox())
523 return; 546 return;
524 const LayoutBox& box = toLayoutBox(object); 547 const LayoutBox& box = toLayoutBox(object);
525 548 // The <input> elements can't have contents thus CSS overflow property
526 // The <input> elements can't have contents thus CSS overflow property doesn't 549 // doesn't apply. However for layout purposes we do generate child layout
527 // apply. However for layout purposes we do generate child layout objects for 550 // objects for them, e.g. button label. We should clip the overflow from
528 // them, e.g. button label. We should clip the overflow from those children. 551 // those children. This is called control clip and we technically treat them
529 // This is called control clip and we technically treat them like overflow 552 // like overflow clip.
530 // clip.
531 LayoutRect clipRect; 553 LayoutRect clipRect;
532 if (box.hasControlClip()) { 554 if (box.hasControlClip()) {
533 clipRect = box.controlClipRect(context.current.paintOffset); 555 clipRect = box.controlClipRect(context.current.paintOffset);
534 } else if (box.hasOverflowClip() || box.styleRef().containsPaint() || 556 } else if (box.hasOverflowClip() || box.styleRef().containsPaint() ||
535 (box.isSVGRoot() && 557 (box.isSVGRoot() &&
536 toLayoutSVGRoot(box).shouldApplyViewportClip())) { 558 toLayoutSVGRoot(box).shouldApplyViewportClip())) {
537 clipRect = LayoutRect( 559 clipRect = LayoutRect(
538 pixelSnappedIntRect(box.overflowClipRect(context.current.paintOffset))); 560 pixelSnappedIntRect(box.overflowClipRect(context.current.paintOffset)));
539 } else { 561 } else {
540 if (auto* properties = object.getMutableForPainting().paintProperties()) { 562 if (auto* properties = object.getMutableForPainting().paintProperties()) {
541 properties->clearInnerBorderRadiusClip(); 563 properties->clearInnerBorderRadiusClip();
542 properties->clearOverflowClip(); 564 properties->clearOverflowClip();
543 } 565 }
544 return; 566 return;
545 } 567 }
546 568
569 const auto* currentClip = context.current.clip;
547 if (box.styleRef().hasBorderRadius()) { 570 if (box.styleRef().hasBorderRadius()) {
548 auto innerBorder = box.styleRef().getRoundedInnerBorderFor( 571 auto innerBorder = box.styleRef().getRoundedInnerBorderFor(
549 LayoutRect(context.current.paintOffset, box.size())); 572 LayoutRect(context.current.paintOffset, box.size()));
550 context.current.clip = 573 object.getMutableForPainting()
551 object.getMutableForPainting() 574 .ensurePaintProperties()
552 .ensurePaintProperties() 575 .updateInnerBorderRadiusClip(context.current.clip,
553 .updateInnerBorderRadiusClip( 576 context.current.transform, innerBorder);
554 context.current.clip, context.current.transform, innerBorder); 577 currentClip = object.paintProperties()->innerBorderRadiusClip();
555 } else if (auto* properties = 578 } else if (auto* properties =
556 object.getMutableForPainting().paintProperties()) { 579 object.getMutableForPainting().paintProperties()) {
557 properties->clearInnerBorderRadiusClip(); 580 properties->clearInnerBorderRadiusClip();
558 } 581 }
559 582
560 context.current.clip = 583 object.getMutableForPainting().ensurePaintProperties().updateOverflowClip(
561 object.getMutableForPainting().ensurePaintProperties().updateOverflowClip( 584 currentClip, context.current.transform,
562 context.current.clip, context.current.transform, 585 FloatRoundedRect(FloatRect(clipRect)));
563 FloatRoundedRect(FloatRect(clipRect))); 586
587 const auto* properties = object.paintProperties();
588 if (properties && properties->overflowClip())
589 context.current.clip = properties->overflowClip();
564 } 590 }
565 591
566 static FloatPoint perspectiveOrigin(const LayoutBox& box) { 592 static FloatPoint perspectiveOrigin(const LayoutBox& box) {
567 const ComputedStyle& style = box.styleRef(); 593 const ComputedStyle& style = box.styleRef();
568 FloatSize borderBoxSize(box.size()); 594 FloatSize borderBoxSize(box.size());
569 return FloatPoint( 595 return FloatPoint(
570 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), 596 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()),
571 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())); 597 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height()));
572 } 598 }
573 599
574 void PaintPropertyTreeBuilder::updatePerspective( 600 void PaintPropertyTreeBuilder::updatePerspective(
575 const LayoutObject& object, 601 const LayoutObject& object,
576 PaintPropertyTreeBuilderContext& context) { 602 PaintPropertyTreeBuilderContext& context) {
577 const ComputedStyle& style = object.styleRef(); 603 const ComputedStyle& style = object.styleRef();
578 if (!object.isBox() || !style.hasPerspective()) { 604 if (object.isBox() && style.hasPerspective()) {
605 // The perspective node must not flatten (else nothing will get
606 // perspective), but it should still extend the rendering context as
607 // most transform nodes do.
608 TransformationMatrix matrix =
609 TransformationMatrix().applyPerspective(style.perspective());
610 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) +
611 toLayoutSize(context.current.paintOffset);
612 object.getMutableForPainting().ensurePaintProperties().updatePerspective(
613 context.current.transform, matrix, origin,
614 context.current.shouldFlattenInheritedTransform,
615 context.current.renderingContextID);
616 } else {
579 if (auto* properties = object.getMutableForPainting().paintProperties()) 617 if (auto* properties = object.getMutableForPainting().paintProperties())
580 properties->clearPerspective(); 618 properties->clearPerspective();
581 return;
582 } 619 }
583 620
584 // The perspective node must not flatten (else nothing will get 621 const auto* properties = object.paintProperties();
585 // perspective), but it should still extend the rendering context as most 622 if (properties && properties->perspective()) {
586 // transform nodes do. 623 context.current.transform = properties->perspective();
587 TransformationMatrix matrix = 624 context.current.shouldFlattenInheritedTransform = false;
588 TransformationMatrix().applyPerspective(style.perspective()); 625 }
589 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) +
590 toLayoutSize(context.current.paintOffset);
591 context.current.transform =
592 object.getMutableForPainting().ensurePaintProperties().updatePerspective(
593 context.current.transform, matrix, origin,
594 context.current.shouldFlattenInheritedTransform,
595 context.current.renderingContextID);
596 context.current.shouldFlattenInheritedTransform = false;
597 } 626 }
598 627
599 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform( 628 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(
600 const LayoutObject& object, 629 const LayoutObject& object,
601 PaintPropertyTreeBuilderContext& context) { 630 PaintPropertyTreeBuilderContext& context) {
602 if (!object.isSVGRoot()) 631 if (!object.isSVGRoot())
603 return; 632 return;
604 633
605 AffineTransform transformToBorderBox = 634 AffineTransform transformToBorderBox =
606 SVGRootPainter(toLayoutSVGRoot(object)) 635 SVGRootPainter(toLayoutSVGRoot(object))
607 .transformToPixelSnappedBorderBox(context.current.paintOffset); 636 .transformToPixelSnappedBorderBox(context.current.paintOffset);
637 if (!transformToBorderBox.isIdentity()) {
638 object.getMutableForPainting()
639 .ensurePaintProperties()
640 .updateSvgLocalToBorderBoxTransform(
641 context.current.transform, transformToBorderBox, FloatPoint3D());
642 } else {
643 if (auto* properties = object.getMutableForPainting().paintProperties())
644 properties->clearSvgLocalToBorderBoxTransform();
645 }
608 646
647 const auto* properties = object.paintProperties();
648 if (properties && properties->svgLocalToBorderBoxTransform()) {
649 context.current.transform = properties->svgLocalToBorderBoxTransform();
650 context.current.shouldFlattenInheritedTransform = false;
651 context.current.renderingContextID = 0;
652 }
609 // The paint offset is included in |transformToBorderBox| so SVG does not need 653 // The paint offset is included in |transformToBorderBox| so SVG does not need
610 // to handle paint offset internally. 654 // to handle paint offset internally.
611 context.current.paintOffset = LayoutPoint(); 655 context.current.paintOffset = LayoutPoint();
612
613 if (transformToBorderBox.isIdentity()) {
614 if (auto* properties = object.getMutableForPainting().paintProperties())
615 properties->clearSvgLocalToBorderBoxTransform();
616 return;
617 }
618
619 context.current.transform =
620 object.getMutableForPainting()
621 .ensurePaintProperties()
622 .updateSvgLocalToBorderBoxTransform(
623 context.current.transform, transformToBorderBox, FloatPoint3D());
624 context.current.shouldFlattenInheritedTransform = false;
625 context.current.renderingContextID = 0;
626 } 656 }
627 657
628 void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( 658 void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation(
629 const LayoutObject& object, 659 const LayoutObject& object,
630 PaintPropertyTreeBuilderContext& context) { 660 PaintPropertyTreeBuilderContext& context) {
631 if (object.hasOverflowClip()) { 661 if (object.hasOverflowClip()) {
632 const LayoutBox& box = toLayoutBox(object); 662 const LayoutBox& box = toLayoutBox(object);
633 const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea(); 663 const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea();
634 IntSize scrollOffset = box.scrolledContentOffset(); 664 IntSize scrollOffset = box.scrolledContentOffset();
635 if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) { 665 if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) {
636 TransformationMatrix matrix = TransformationMatrix().translate( 666 TransformationMatrix matrix = TransformationMatrix().translate(
637 -scrollOffset.width(), -scrollOffset.height()); 667 -scrollOffset.width(), -scrollOffset.height());
638 context.current.transform = 668 object.getMutableForPainting()
639 object.getMutableForPainting() 669 .ensurePaintProperties()
640 .ensurePaintProperties() 670 .updateScrollTranslation(
641 .updateScrollTranslation( 671 context.current.transform, matrix, FloatPoint3D(),
642 context.current.transform, matrix, FloatPoint3D(), 672 context.current.shouldFlattenInheritedTransform,
643 context.current.shouldFlattenInheritedTransform, 673 context.current.renderingContextID);
644 context.current.renderingContextID);
645 674
646 IntSize scrollClip = scrollableArea->visibleContentRect().size(); 675 IntSize scrollClip = scrollableArea->visibleContentRect().size();
647 IntSize scrollBounds = scrollableArea->contentsSize(); 676 IntSize scrollBounds = scrollableArea->contentsSize();
648 bool userScrollableHorizontal = 677 bool userScrollableHorizontal =
649 scrollableArea->userInputScrollable(HorizontalScrollbar); 678 scrollableArea->userInputScrollable(HorizontalScrollbar);
650 bool userScrollableVertical = 679 bool userScrollableVertical =
651 scrollableArea->userInputScrollable(VerticalScrollbar); 680 scrollableArea->userInputScrollable(VerticalScrollbar);
652 context.current.scroll = 681 object.getMutableForPainting().ensurePaintProperties().updateScroll(
653 object.getMutableForPainting().ensurePaintProperties().updateScroll( 682 context.current.scroll, object.paintProperties()->scrollTranslation(),
654 context.current.scroll, context.current.transform, scrollClip, 683 scrollClip, scrollBounds, userScrollableHorizontal,
655 scrollBounds, userScrollableHorizontal, userScrollableVertical); 684 userScrollableVertical);
656 685 } else {
657 context.current.shouldFlattenInheritedTransform = false; 686 // Ensure pre-existing properties are cleared when there is no
658 return; 687 // scrolling.
688 auto* properties = object.getMutableForPainting().paintProperties();
689 if (properties) {
690 properties->clearScrollTranslation();
691 properties->clearScroll();
692 }
659 } 693 }
660 } 694 }
661 695
662 if (auto* properties = object.getMutableForPainting().paintProperties()) { 696 if (object.paintProperties() && object.paintProperties()->scroll()) {
663 properties->clearScrollTranslation(); 697 context.current.transform = object.paintProperties()->scrollTranslation();
664 properties->clearScroll(); 698 const auto* scroll = object.paintProperties()->scroll();
699 // TODO(pdr): Remove this const cast.
700 context.current.scroll = const_cast<ScrollPaintPropertyNode*>(scroll);
701 context.current.shouldFlattenInheritedTransform = false;
665 } 702 }
666 } 703 }
667 704
668 void PaintPropertyTreeBuilder::updateOutOfFlowContext( 705 void PaintPropertyTreeBuilder::updateOutOfFlowContext(
669 const LayoutObject& object, 706 const LayoutObject& object,
670 PaintPropertyTreeBuilderContext& context) { 707 PaintPropertyTreeBuilderContext& context) {
671 if (object.canContainAbsolutePositionObjects()) { 708 if (object.canContainAbsolutePositionObjects()) {
672 context.absolutePosition = context.current; 709 context.absolutePosition = context.current;
673 context.containerForAbsolutePosition = &object; 710 context.containerForAbsolutePosition = &object;
674 } 711 }
(...skipping 19 matching lines...) Expand all
694 // absolute position container. However for fixed-position descendants we 731 // absolute position container. However for fixed-position descendants we
695 // need to insert the clip here if we are not a containing block ancestor of 732 // need to insert the clip here if we are not a containing block ancestor of
696 // them. 733 // them.
697 auto* cssClip = object.getMutableForPainting().paintProperties()->cssClip(); 734 auto* cssClip = object.getMutableForPainting().paintProperties()->cssClip();
698 735
699 // Before we actually create anything, check whether in-flow context and 736 // Before we actually create anything, check whether in-flow context and
700 // fixed-position context has exactly the same clip. Reuse if possible. 737 // fixed-position context has exactly the same clip. Reuse if possible.
701 if (context.fixedPosition.clip == cssClip->parent()) { 738 if (context.fixedPosition.clip == cssClip->parent()) {
702 context.fixedPosition.clip = cssClip; 739 context.fixedPosition.clip = cssClip;
703 } else { 740 } else {
704 context.fixedPosition.clip = 741 object.getMutableForPainting()
705 object.getMutableForPainting() 742 .ensurePaintProperties()
706 .ensurePaintProperties() 743 .updateCssClipFixedPosition(context.fixedPosition.clip,
707 .updateCssClipFixedPosition( 744 const_cast<TransformPaintPropertyNode*>(
708 context.fixedPosition.clip, 745 cssClip->localTransformSpace()),
709 const_cast<TransformPaintPropertyNode*>( 746 cssClip->clipRect());
710 cssClip->localTransformSpace()), 747 const auto* properties = object.paintProperties();
711 cssClip->clipRect()); 748 if (properties && properties->cssClipFixedPosition())
749 context.fixedPosition.clip = properties->cssClipFixedPosition();
712 return; 750 return;
713 } 751 }
714 } 752 }
715 753
716 if (auto* properties = object.getMutableForPainting().paintProperties()) 754 if (auto* properties = object.getMutableForPainting().paintProperties())
717 properties->clearCssClipFixedPosition(); 755 properties->clearCssClipFixedPosition();
718 } 756 }
719 757
720 // Override ContainingBlockContext based on the properties of a containing block 758 // Override ContainingBlockContext based on the properties of a containing block
721 // that was previously walked in a subtree other than the current subtree being 759 // that was previously walked in a subtree other than the current subtree being
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). 870 // Similar adjustment is done in LayoutTableCell::offsetFromContainer().
833 if (boxModelObject.isTableCell()) { 871 if (boxModelObject.isTableCell()) {
834 LayoutObject* parentRow = boxModelObject.parent(); 872 LayoutObject* parentRow = boxModelObject.parent();
835 ASSERT(parentRow && parentRow->isTableRow()); 873 ASSERT(parentRow && parentRow->isTableRow());
836 context.current.paintOffset.moveBy( 874 context.current.paintOffset.moveBy(
837 -toLayoutBox(parentRow)->topLeftLocation()); 875 -toLayoutBox(parentRow)->topLeftLocation());
838 } 876 }
839 } 877 }
840 } 878 }
841 879
842 void PaintPropertyTreeBuilder::buildTreeNodesForSelf( 880 void PaintPropertyTreeBuilder::updatePropertiesAndContextForSelf(
843 const LayoutObject& object, 881 const LayoutObject& object,
844 PaintPropertyTreeBuilderContext& context) { 882 PaintPropertyTreeBuilderContext& context) {
845 if (!object.isBoxModelObject() && !object.isSVG()) 883 if (!object.isBoxModelObject() && !object.isSVG())
846 return; 884 return;
847 885
848 deriveBorderBoxFromContainerContext(object, context); 886 deriveBorderBoxFromContainerContext(object, context);
849 887
850 updatePaintOffsetTranslation(object, context); 888 updatePaintOffsetTranslation(object, context);
851 updateTransform(object, context); 889 updateTransform(object, context);
852 updateEffect(object, context); 890 updateEffect(object, context);
853 updateCssClip(object, context); 891 updateCssClip(object, context);
854 updateLocalBorderBoxContext(object, context); 892 updateLocalBorderBoxContext(object, context);
855 updateScrollbarPaintOffset(object, context); 893 updateScrollbarPaintOffset(object, context);
856 updateMainThreadScrollingReasons(object, context); 894 updateMainThreadScrollingReasons(object, context);
857 } 895 }
858 896
859 void PaintPropertyTreeBuilder::buildTreeNodesForChildren( 897 void PaintPropertyTreeBuilder::updatePropertiesAndContextForChildren(
860 const LayoutObject& object, 898 const LayoutObject& object,
861 PaintPropertyTreeBuilderContext& context) { 899 PaintPropertyTreeBuilderContext& context) {
862 if (!object.isBoxModelObject() && !object.isSVG()) 900 if (!object.isBoxModelObject() && !object.isSVG())
863 return; 901 return;
864 902
865 updateOverflowClip(object, context); 903 updateOverflowClip(object, context);
866 updatePerspective(object, context); 904 updatePerspective(object, context);
867 updateSvgLocalToBorderBoxTransform(object, context); 905 updateSvgLocalToBorderBoxTransform(object, context);
868 updateScrollAndScrollTranslation(object, context); 906 updateScrollAndScrollTranslation(object, context);
869 updateOutOfFlowContext(object, context); 907 updateOutOfFlowContext(object, context);
870 } 908 }
871 909
872 } // namespace blink 910 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698