OLD | NEW |
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/layout/LayoutPart.h" | 8 #include "core/layout/LayoutPart.h" |
9 #include "core/layout/LayoutView.h" | 9 #include "core/layout/LayoutView.h" |
10 #include "core/paint/ObjectPaintProperties.h" | 10 #include "core/paint/ObjectPaintProperties.h" |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje
ct& object, PaintPropertyTreeBuilderContext& context) | 207 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje
ct& object, PaintPropertyTreeBuilderContext& context) |
208 { | 208 { |
209 const ComputedStyle& style = object.styleRef(); | 209 const ComputedStyle& style = object.styleRef(); |
210 if (!style.hasOpacity()) | 210 if (!style.hasOpacity()) |
211 return nullptr; | 211 return nullptr; |
212 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre
ate(style.opacity(), context.currentEffect); | 212 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre
ate(style.opacity(), context.currentEffect); |
213 context.currentEffect = newEffectNode.get(); | 213 context.currentEffect = newEffectNode.get(); |
214 return newEffectNode.release(); | 214 return newEffectNode.release(); |
215 } | 215 } |
216 | 216 |
| 217 static PassRefPtr<ClipPaintPropertyNode> createCSSClipIfNeeded(const LayoutObjec
t& object, PaintPropertyTreeBuilderContext& context) |
| 218 { |
| 219 if (!object.hasClip()) |
| 220 return nullptr; |
| 221 ASSERT(object.canContainAbsolutePositionObjects()); |
| 222 |
| 223 // Create clip node for descendants that are not fixed position. |
| 224 // We don't have to setup context.clipForAbsolutePosition here because this
object must be |
| 225 // a container for absolute position descendants, and will copy from in-flow
context later |
| 226 // at updateOutOfFlowContext() step. |
| 227 LayoutRect clipRect = toLayoutBox(object).clipRect(context.paintOffset); |
| 228 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClip = ClipPaintPropertyNode:
:create( |
| 229 context.currentTransform, |
| 230 FloatRoundedRect(FloatRect(clipRect)), |
| 231 context.currentClip); |
| 232 context.currentClip = newClipNodeForCSSClip.get(); |
| 233 |
| 234 return newClipNodeForCSSClip.release(); |
| 235 } |
| 236 |
217 // TODO(trchen): Remove this once we bake the paint offset into frameRect. | 237 // TODO(trchen): Remove this once we bake the paint offset into frameRect. |
218 static PassRefPtr<TransformPaintPropertyNode> createScrollbarPaintOffsetIfNeeded
(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) | 238 static PassRefPtr<TransformPaintPropertyNode> createScrollbarPaintOffsetIfNeeded
(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) |
219 { | 239 { |
220 IntPoint roundedPaintOffset = roundedIntPoint(context.paintOffset); | 240 IntPoint roundedPaintOffset = roundedIntPoint(context.paintOffset); |
221 if (roundedPaintOffset == IntPoint()) | 241 if (roundedPaintOffset == IntPoint()) |
222 return nullptr; | 242 return nullptr; |
223 | 243 |
224 if (!object.isBoxModelObject()) | 244 if (!object.isBoxModelObject()) |
225 return nullptr; | 245 return nullptr; |
226 PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).ge
tScrollableArea(); | 246 PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).ge
tScrollableArea(); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 if (scrollOffset.isZero() && !layer->scrollsOverflow()) | 322 if (scrollOffset.isZero() && !layer->scrollsOverflow()) |
303 return nullptr; | 323 return nullptr; |
304 | 324 |
305 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr
ansformPaintPropertyNode::create( | 325 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr
ansformPaintPropertyNode::create( |
306 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he
ight()), | 326 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he
ight()), |
307 FloatPoint3D(), context.currentTransform); | 327 FloatPoint3D(), context.currentTransform); |
308 context.currentTransform = newTransformNodeForScrollTranslation.get(); | 328 context.currentTransform = newTransformNodeForScrollTranslation.get(); |
309 return newTransformNodeForScrollTranslation.release(); | 329 return newTransformNodeForScrollTranslation.release(); |
310 } | 330 } |
311 | 331 |
312 static void updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTree
BuilderContext& context) | 332 static void updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTree
BuilderContext& context, ClipPaintPropertyNode* newClipNodeForCSSClip, RefPtr<Cl
ipPaintPropertyNode>& newClipNodeForCSSClipFixedPosition) |
313 { | 333 { |
314 // At the html->svg boundary (see: createPaintOffsetTranslationIfNeeded) the
currentTransform is | 334 // At the html->svg boundary (see: createPaintOffsetTranslationIfNeeded) the
currentTransform is |
315 // up-to-date for all children of the svg root element. Additionally, inside
SVG, all positioning | 335 // up-to-date for all children of the svg root element. Additionally, inside
SVG, all positioning |
316 // uses transforms. Therefore, we only need to check createdNewTransform and
isSVGRoot() to | 336 // uses transforms. Therefore, we only need to check createdNewTransform and
isSVGRoot() to |
317 // ensure out-of-flow and fixed positioning is correct at the svg->html boun
dary. | 337 // ensure out-of-flow and fixed positioning is correct at the svg->html boun
dary. |
318 | 338 |
319 if (object.canContainAbsolutePositionObjects()) { | 339 if (object.canContainAbsolutePositionObjects()) { |
320 context.transformForAbsolutePosition = context.currentTransform; | 340 context.transformForAbsolutePosition = context.currentTransform; |
321 context.paintOffsetForAbsolutePosition = context.paintOffset; | 341 context.paintOffsetForAbsolutePosition = context.paintOffset; |
322 context.clipForAbsolutePosition = context.currentClip; | 342 context.clipForAbsolutePosition = context.currentClip; |
323 } | 343 } |
324 | 344 |
325 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram
eView | 345 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram
eView |
326 // paint properties for rootLayerScrolls. | 346 // paint properties for rootLayerScrolls. |
327 if (!object.isLayoutView() && object.canContainFixedPositionObjects()) { | 347 if (!object.isLayoutView() && object.canContainFixedPositionObjects()) { |
328 context.transformForFixedPosition = context.currentTransform; | 348 context.transformForFixedPosition = context.currentTransform; |
329 context.paintOffsetForFixedPosition = context.paintOffset; | 349 context.paintOffsetForFixedPosition = context.paintOffset; |
330 context.clipForFixedPosition = context.currentClip; | 350 context.clipForFixedPosition = context.currentClip; |
| 351 } else if (newClipNodeForCSSClip) { |
| 352 // CSS clip applies to all descendants, even if this object is not a con
taining block |
| 353 // ancestor of the descendant. It is okay for absolute-position descenda
nts because |
| 354 // having CSS clip implies being absolute position container. However fo
r fixed-position |
| 355 // descendants we need to insert the clip here if we are not a containin
g block ancestor |
| 356 // of them. |
| 357 |
| 358 // Before we actually create anything, check whether in-flow context and
fixed-position |
| 359 // context has exactly the same clip. Reuse if possible. |
| 360 if (context.clipForFixedPosition == newClipNodeForCSSClip->parent()) { |
| 361 context.clipForFixedPosition = newClipNodeForCSSClip; |
| 362 return; |
| 363 } |
| 364 |
| 365 newClipNodeForCSSClipFixedPosition = ClipPaintPropertyNode::create( |
| 366 const_cast<TransformPaintPropertyNode*>(newClipNodeForCSSClip->local
TransformSpace()), |
| 367 newClipNodeForCSSClip->clipRect(), |
| 368 context.clipForFixedPosition); |
| 369 context.clipForFixedPosition = newClipNodeForCSSClipFixedPosition.get(); |
331 } | 370 } |
332 } | 371 } |
333 | 372 |
334 static PassOwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordTreeCon
textIfNeeded(LayoutObject& object, const PaintPropertyTreeBuilderContext& contex
t) | 373 static PassOwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordTreeCon
textIfNeeded(LayoutObject& object, const PaintPropertyTreeBuilderContext& contex
t) |
335 { | 374 { |
336 // Note: Currently only layer painter makes use of the pre-computed context. | 375 // Note: Currently only layer painter makes use of the pre-computed context. |
337 // This condition may be loosened with no adverse effects beside memory use. | 376 // This condition may be loosened with no adverse effects beside memory use. |
338 if (!object.hasLayer()) | 377 if (!object.hasLayer()) |
339 return nullptr; | 378 return nullptr; |
340 | 379 |
341 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordedContext = ad
optPtr(new ObjectPaintProperties::LocalBorderBoxProperties); | 380 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordedContext = ad
optPtr(new ObjectPaintProperties::LocalBorderBoxProperties); |
342 recordedContext->paintOffset = context.paintOffset; | 381 recordedContext->paintOffset = context.paintOffset; |
343 recordedContext->transform = context.currentTransform; | 382 recordedContext->transform = context.currentTransform; |
344 recordedContext->clip = context.currentClip; | 383 recordedContext->clip = context.currentClip; |
345 recordedContext->effect = context.currentEffect; | 384 recordedContext->effect = context.currentEffect; |
346 return recordedContext.release(); | 385 return recordedContext.release(); |
347 } | 386 } |
348 | 387 |
349 void PaintPropertyTreeBuilder::walk(LayoutObject& object, const PaintPropertyTre
eBuilderContext& context) | 388 void PaintPropertyTreeBuilder::walk(LayoutObject& object, const PaintPropertyTre
eBuilderContext& context) |
350 { | 389 { |
351 PaintPropertyTreeBuilderContext localContext(context); | 390 PaintPropertyTreeBuilderContext localContext(context); |
352 | 391 |
353 deriveBorderBoxFromContainerContext(object, localContext); | 392 deriveBorderBoxFromContainerContext(object, localContext); |
354 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation
= createPaintOffsetTranslationIfNeeded(object, localContext); | 393 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation
= createPaintOffsetTranslationIfNeeded(object, localContext); |
355 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran
sformIfNeeded(object, localContext); | 394 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran
sformIfNeeded(object, localContext); |
356 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object,
localContext); | 395 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object,
localContext); |
| 396 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClip = createCSSClipIfNeeded(
object, localContext); |
357 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> newRecordedContext =
recordTreeContextIfNeeded(object, localContext); | 397 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> newRecordedContext =
recordTreeContextIfNeeded(object, localContext); |
358 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollbarPaintOffset =
createScrollbarPaintOffsetIfNeeded(object, localContext); | 398 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollbarPaintOffset =
createScrollbarPaintOffsetIfNeeded(object, localContext); |
359 RefPtr<ClipPaintPropertyNode> newClipNodeForOverflowClip = createOverflowCli
pIfNeeded(object, localContext); | 399 RefPtr<ClipPaintPropertyNode> newClipNodeForOverflowClip = createOverflowCli
pIfNeeded(object, localContext); |
360 // TODO(trchen): Insert flattening transform here, as specified by | 400 // TODO(trchen): Insert flattening transform here, as specified by |
361 // http://www.w3.org/TR/css3-transforms/#transform-style-property | 401 // http://www.w3.org/TR/css3-transforms/#transform-style-property |
362 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe
rspectiveIfNeeded(object, localContext); | 402 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe
rspectiveIfNeeded(object, localContext); |
363 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr
eateScrollTranslationIfNeeded(object, localContext); | 403 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr
eateScrollTranslationIfNeeded(object, localContext); |
364 updateOutOfFlowContext(object, localContext); | 404 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClipFixedPosition; |
| 405 updateOutOfFlowContext(object, localContext, newClipNodeForCSSClip.get(), ne
wClipNodeForCSSClipFixedPosition); |
365 | 406 |
366 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor
m || newEffectNode || newClipNodeForOverflowClip || newTransformNodeForPerspecti
ve || newTransformNodeForScrollTranslation || newTransformNodeForScrollbarPaintO
ffset || newRecordedContext) { | 407 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor
m || newEffectNode || newClipNodeForCSSClip || newClipNodeForCSSClipFixedPositio
n || newClipNodeForOverflowClip || newTransformNodeForPerspective || newTransfor
mNodeForScrollTranslation || newTransformNodeForScrollbarPaintOffset || newRecor
dedContext) { |
367 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper
ties::create( | 408 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper
ties::create( |
368 newTransformNodeForPaintOffsetTranslation.release(), | 409 newTransformNodeForPaintOffsetTranslation.release(), |
369 newTransformNodeForTransform.release(), | 410 newTransformNodeForTransform.release(), |
370 newEffectNode.release(), | 411 newEffectNode.release(), |
| 412 newClipNodeForCSSClip.release(), |
| 413 newClipNodeForCSSClipFixedPosition.release(), |
371 newClipNodeForOverflowClip.release(), | 414 newClipNodeForOverflowClip.release(), |
372 newTransformNodeForPerspective.release(), | 415 newTransformNodeForPerspective.release(), |
373 newTransformNodeForScrollTranslation.release(), | 416 newTransformNodeForScrollTranslation.release(), |
374 newTransformNodeForScrollbarPaintOffset.release(), | 417 newTransformNodeForScrollbarPaintOffset.release(), |
375 newRecordedContext.release()); | 418 newRecordedContext.release()); |
376 object.setObjectPaintProperties(updatedPaintProperties.release()); | 419 object.setObjectPaintProperties(updatedPaintProperties.release()); |
377 } else { | 420 } else { |
378 object.clearObjectPaintProperties(); | 421 object.clearObjectPaintProperties(); |
379 } | 422 } |
380 | 423 |
381 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne
xtSibling()) { | 424 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne
xtSibling()) { |
382 if (child->isBoxModelObject() || child->isSVG()) | 425 if (child->isBoxModelObject() || child->isSVG()) |
383 walk(*child, localContext); | 426 walk(*child, localContext); |
384 } | 427 } |
385 | 428 |
386 if (object.isLayoutPart()) { | 429 if (object.isLayoutPart()) { |
387 Widget* widget = toLayoutPart(object).widget(); | 430 Widget* widget = toLayoutPart(object).widget(); |
388 if (widget && widget->isFrameView()) | 431 if (widget && widget->isFrameView()) |
389 walk(*toFrameView(widget), localContext); | 432 walk(*toFrameView(widget), localContext); |
390 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). | 433 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). |
391 } | 434 } |
392 } | 435 } |
393 | 436 |
394 } // namespace blink | 437 } // namespace blink |
OLD | NEW |