OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights |
| 3 * reserved. |
3 * | 4 * |
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 5 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
5 * | 6 * |
6 * Other contributors: | 7 * Other contributors: |
7 * Robert O'Callahan <roc+@cs.cmu.edu> | 8 * Robert O'Callahan <roc+@cs.cmu.edu> |
8 * David Baron <dbaron@fas.harvard.edu> | 9 * David Baron <dbaron@fas.harvard.edu> |
9 * Christian Biesinger <cbiesinger@web.de> | 10 * Christian Biesinger <cbiesinger@web.de> |
10 * Randall Jesup <rjesup@wgate.com> | 11 * Randall Jesup <rjesup@wgate.com> |
11 * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> | 12 * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> |
12 * Josh Soref <timeless@mac.com> | 13 * Josh Soref <timeless@mac.com> |
13 * Boris Zbarsky <bzbarsky@mit.edu> | 14 * Boris Zbarsky <bzbarsky@mit.edu> |
14 * | 15 * |
15 * This library is free software; you can redistribute it and/or | 16 * This library is free software; you can redistribute it and/or |
16 * modify it under the terms of the GNU Lesser General Public | 17 * modify it under the terms of the GNU Lesser General Public |
17 * License as published by the Free Software Foundation; either | 18 * License as published by the Free Software Foundation; either |
18 * version 2.1 of the License, or (at your option) any later version. | 19 * version 2.1 of the License, or (at your option) any later version. |
19 * | 20 * |
20 * This library is distributed in the hope that it will be useful, | 21 * This library is distributed in the hope that it will be useful, |
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
23 * Lesser General Public License for more details. | 24 * Lesser General Public License for more details. |
24 * | 25 * |
25 * You should have received a copy of the GNU Lesser General Public | 26 * You should have received a copy of the GNU Lesser General Public |
26 * License along with this library; if not, write to the Free Software | 27 * License along with this library; if not, write to the Free Software |
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 US
A | 28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
28 * | 29 * |
29 * Alternatively, the contents of this file may be used under the terms | 30 * Alternatively, the contents of this file may be used under the terms |
30 * of either the Mozilla Public License Version 1.1, found at | 31 * of either the Mozilla Public License Version 1.1, found at |
31 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public | 32 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public |
32 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html | 33 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html |
33 * (the "GPL"), in which case the provisions of the MPL or the GPL are | 34 * (the "GPL"), in which case the provisions of the MPL or the GPL are |
34 * applicable instead of those above. If you wish to allow use of your | 35 * applicable instead of those above. If you wish to allow use of your |
35 * version of this file only under the terms of one of those two | 36 * version of this file only under the terms of one of those two |
36 * licenses (the MPL or the GPL) and not to allow others to use your | 37 * licenses (the MPL or the GPL) and not to allow others to use your |
37 * version of this file under the LGPL, indicate your decision by | 38 * version of this file under the LGPL, indicate your decision by |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 return m_layoutObject->visualRect(); | 220 return m_layoutObject->visualRect(); |
220 } | 221 } |
221 | 222 |
222 PaintLayerCompositor* PaintLayer::compositor() const { | 223 PaintLayerCompositor* PaintLayer::compositor() const { |
223 if (!layoutObject()->view()) | 224 if (!layoutObject()->view()) |
224 return 0; | 225 return 0; |
225 return layoutObject()->view()->compositor(); | 226 return layoutObject()->view()->compositor(); |
226 } | 227 } |
227 | 228 |
228 void PaintLayer::contentChanged(ContentChangeType changeType) { | 229 void PaintLayer::contentChanged(ContentChangeType changeType) { |
229 // updateLayerCompositingState will query compositingReasons for accelerated o
verflow scrolling. | 230 // updateLayerCompositingState will query compositingReasons for accelerated |
230 // This is tripped by LayoutTests/compositing/content-changed-chicken-egg.html | 231 // overflow scrolling. This is tripped by |
| 232 // LayoutTests/compositing/content-changed-chicken-egg.html |
231 DisableCompositingQueryAsserts disabler; | 233 DisableCompositingQueryAsserts disabler; |
232 | 234 |
233 if (changeType == CanvasChanged) | 235 if (changeType == CanvasChanged) |
234 compositor()->setNeedsCompositingUpdate( | 236 compositor()->setNeedsCompositingUpdate( |
235 CompositingUpdateAfterCompositingInputChange); | 237 CompositingUpdateAfterCompositingInputChange); |
236 | 238 |
237 if (changeType == CanvasContextChanged) { | 239 if (changeType == CanvasContextChanged) { |
238 compositor()->setNeedsCompositingUpdate( | 240 compositor()->setNeedsCompositingUpdate( |
239 CompositingUpdateAfterCompositingInputChange); | 241 CompositingUpdateAfterCompositingInputChange); |
240 | 242 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 } | 284 } |
283 | 285 |
284 void PaintLayer::updateLayerPositionsAfterLayout() { | 286 void PaintLayer::updateLayerPositionsAfterLayout() { |
285 TRACE_EVENT0("blink,benchmark", | 287 TRACE_EVENT0("blink,benchmark", |
286 "PaintLayer::updateLayerPositionsAfterLayout"); | 288 "PaintLayer::updateLayerPositionsAfterLayout"); |
287 | 289 |
288 clipper().clearClipRectsIncludingDescendants(); | 290 clipper().clearClipRectsIncludingDescendants(); |
289 updateLayerPositionRecursive(); | 291 updateLayerPositionRecursive(); |
290 | 292 |
291 { | 293 { |
292 // FIXME: Remove incremental compositing updates after fixing the chicken/eg
g issues | 294 // FIXME: Remove incremental compositing updates after fixing the |
293 // https://code.google.com/p/chromium/issues/detail?id=343756 | 295 // chicken/egg issues, https://crbug.com/343756 |
294 DisableCompositingQueryAsserts disabler; | 296 DisableCompositingQueryAsserts disabler; |
295 updatePaginationRecursive(enclosingPaginationLayer()); | 297 updatePaginationRecursive(enclosingPaginationLayer()); |
296 } | 298 } |
297 } | 299 } |
298 | 300 |
299 void PaintLayer::updateLayerPositionRecursive() { | 301 void PaintLayer::updateLayerPositionRecursive() { |
300 updateLayerPosition(); | 302 updateLayerPosition(); |
301 | 303 |
302 // FIXME(400589): We would like to do this in PaintLayerScrollableArea::update
AfterLayout, | 304 // FIXME(400589): We would like to do this in |
303 // but it depends on the size computed by updateLayerPosition. | 305 // PaintLayerScrollableArea::updateAfterLayout, but it depends on the size |
| 306 // computed by updateLayerPosition. |
304 if (m_scrollableArea) { | 307 if (m_scrollableArea) { |
305 if (ScrollAnimatorBase* scrollAnimator = | 308 if (ScrollAnimatorBase* scrollAnimator = |
306 m_scrollableArea->existingScrollAnimator()) | 309 m_scrollableArea->existingScrollAnimator()) |
307 scrollAnimator->updateAfterLayout(); | 310 scrollAnimator->updateAfterLayout(); |
308 } | 311 } |
309 | 312 |
310 // FIXME: We should be able to remove this call because we don't care about | 313 // FIXME: We should be able to remove this call because we don't care about |
311 // any descendant-dependent flags, but code somewhere else is reading these | 314 // any descendant-dependent flags, but code somewhere else is reading these |
312 // flags and depending on us to update them. | 315 // flags and depending on us to update them. |
313 updateDescendantDependentFlags(); | 316 updateDescendantDependentFlags(); |
(...skipping 14 matching lines...) Expand all Loading... |
328 break; | 331 break; |
329 } | 332 } |
330 } | 333 } |
331 | 334 |
332 m_hasSelfPaintingLayerDescendantDirty = false; | 335 m_hasSelfPaintingLayerDescendantDirty = false; |
333 } | 336 } |
334 | 337 |
335 void PaintLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus() { | 338 void PaintLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus() { |
336 for (PaintLayer* layer = this; layer; layer = layer->parent()) { | 339 for (PaintLayer* layer = this; layer; layer = layer->parent()) { |
337 layer->m_hasSelfPaintingLayerDescendantDirty = true; | 340 layer->m_hasSelfPaintingLayerDescendantDirty = true; |
338 // If we have reached a self-painting layer, we know our parent should have
a self-painting descendant | 341 // If we have reached a self-painting layer, we know our parent should have |
339 // in this case, there is no need to dirty our ancestors further. | 342 // a self-painting descendant in this case, there is no need to dirty our |
| 343 // ancestors further. |
340 if (layer->isSelfPaintingLayer()) { | 344 if (layer->isSelfPaintingLayer()) { |
341 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || | 345 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || |
342 parent()->m_hasSelfPaintingLayerDescendant); | 346 parent()->m_hasSelfPaintingLayerDescendant); |
343 break; | 347 break; |
344 } | 348 } |
345 } | 349 } |
346 } | 350 } |
347 | 351 |
348 bool PaintLayer::scrollsWithViewport() const { | 352 bool PaintLayer::scrollsWithViewport() const { |
349 return (layoutObject()->style()->position() == FixedPosition && | 353 return (layoutObject()->style()->position() == FixedPosition && |
(...skipping 15 matching lines...) Expand all Loading... |
365 updateLayerPositionsAfterScrollRecursive(scrollDelta, | 369 updateLayerPositionsAfterScrollRecursive(scrollDelta, |
366 isPaintInvalidationContainer()); | 370 isPaintInvalidationContainer()); |
367 } | 371 } |
368 | 372 |
369 void PaintLayer::updateLayerPositionsAfterScrollRecursive( | 373 void PaintLayer::updateLayerPositionsAfterScrollRecursive( |
370 const DoubleSize& scrollDelta, | 374 const DoubleSize& scrollDelta, |
371 bool paintInvalidationContainerWasScrolled) { | 375 bool paintInvalidationContainerWasScrolled) { |
372 updateLayerPosition(); | 376 updateLayerPosition(); |
373 if (paintInvalidationContainerWasScrolled && | 377 if (paintInvalidationContainerWasScrolled && |
374 !isPaintInvalidationContainer()) { | 378 !isPaintInvalidationContainer()) { |
375 // Paint invalidation rects are in the coordinate space of the paint invalid
ation container. | 379 // Paint invalidation rects are in the coordinate space of the paint |
376 // If it has scrolled, the rect must be adjusted. Note that it is not safe t
o reset it to | 380 // invalidation container. If it has scrolled, the rect must be adjusted. |
377 // the current bounds rect, as the LayoutObject may have moved since the las
t invalidation. | 381 // Note that it is not safe to reset it to the current bounds rect, as the |
378 // FIXME(416535): Ideally, pending invalidations of scrolling content should
be stored in | 382 // LayoutObject may have moved since the |
379 // the coordinate space of the scrolling content layer, so that they need no
adjustment. | 383 // last invalidation. |
| 384 // FIXME(416535): Ideally, pending invalidations of scrolling content should |
| 385 // be stored in the coordinate space of the scrolling content layer, so that |
| 386 // they need no adjustment. |
380 m_layoutObject->adjustPreviousPaintInvalidationForScrollIfNeeded( | 387 m_layoutObject->adjustPreviousPaintInvalidationForScrollIfNeeded( |
381 scrollDelta); | 388 scrollDelta); |
382 } | 389 } |
383 for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) { | 390 for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) { |
384 child->updateLayerPositionsAfterScrollRecursive( | 391 child->updateLayerPositionsAfterScrollRecursive( |
385 scrollDelta, paintInvalidationContainerWasScrolled && | 392 scrollDelta, paintInvalidationContainerWasScrolled && |
386 !child->isPaintInvalidationContainer()); | 393 !child->isPaintInvalidationContainer()); |
387 } | 394 } |
388 } | 395 } |
389 | 396 |
390 void PaintLayer::updateTransformationMatrix() { | 397 void PaintLayer::updateTransformationMatrix() { |
391 if (TransformationMatrix* transform = this->transform()) { | 398 if (TransformationMatrix* transform = this->transform()) { |
392 LayoutBox* box = layoutBox(); | 399 LayoutBox* box = layoutBox(); |
393 ASSERT(box); | 400 ASSERT(box); |
394 transform->makeIdentity(); | 401 transform->makeIdentity(); |
395 box->style()->applyTransform( | 402 box->style()->applyTransform( |
396 *transform, box->size(), ComputedStyle::IncludeTransformOrigin, | 403 *transform, box->size(), ComputedStyle::IncludeTransformOrigin, |
397 ComputedStyle::IncludeMotionPath, | 404 ComputedStyle::IncludeMotionPath, |
398 ComputedStyle::IncludeIndependentTransformProperties); | 405 ComputedStyle::IncludeIndependentTransformProperties); |
399 makeMatrixRenderable(*transform, compositor()->hasAcceleratedCompositing()); | 406 makeMatrixRenderable(*transform, compositor()->hasAcceleratedCompositing()); |
400 } | 407 } |
401 } | 408 } |
402 | 409 |
403 void PaintLayer::updateTransform(const ComputedStyle* oldStyle, | 410 void PaintLayer::updateTransform(const ComputedStyle* oldStyle, |
404 const ComputedStyle& newStyle) { | 411 const ComputedStyle& newStyle) { |
405 if (oldStyle && newStyle.transformDataEquivalent(*oldStyle)) | 412 if (oldStyle && newStyle.transformDataEquivalent(*oldStyle)) |
406 return; | 413 return; |
407 | 414 |
408 // hasTransform() on the layoutObject is also true when there is transform-sty
le: preserve-3d or perspective set, | 415 // hasTransform() on the layoutObject is also true when there is |
409 // so check style too. | 416 // transform-style: preserve-3d or perspective set, so check style too. |
410 bool hasTransform = | 417 bool hasTransform = |
411 layoutObject()->hasTransformRelatedProperty() && newStyle.hasTransform(); | 418 layoutObject()->hasTransformRelatedProperty() && newStyle.hasTransform(); |
412 bool had3DTransform = has3DTransform(); | 419 bool had3DTransform = has3DTransform(); |
413 | 420 |
414 bool hadTransform = transform(); | 421 bool hadTransform = transform(); |
415 if (hasTransform != hadTransform) { | 422 if (hasTransform != hadTransform) { |
416 if (hasTransform) | 423 if (hasTransform) |
417 ensureRareData().transform = TransformationMatrix::create(); | 424 ensureRareData().transform = TransformationMatrix::create(); |
418 else | 425 else |
419 m_rareData->transform.reset(); | 426 m_rareData->transform.reset(); |
420 | 427 |
421 // PaintLayers with transforms act as clip rects roots, so clear the cached
clip rects here. | 428 // PaintLayers with transforms act as clip rects roots, so clear the cached |
| 429 // clip rects here. |
422 clipper().clearClipRectsIncludingDescendants(); | 430 clipper().clearClipRectsIncludingDescendants(); |
423 } else if (hasTransform) { | 431 } else if (hasTransform) { |
424 clipper().clearClipRectsIncludingDescendants(AbsoluteClipRects); | 432 clipper().clearClipRectsIncludingDescendants(AbsoluteClipRects); |
425 } | 433 } |
426 | 434 |
427 updateTransformationMatrix(); | 435 updateTransformationMatrix(); |
428 | 436 |
429 if (had3DTransform != has3DTransform()) | 437 if (had3DTransform != has3DTransform()) |
430 dirty3DTransformedDescendantStatus(); | 438 dirty3DTransformedDescendantStatus(); |
431 | 439 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 } | 505 } |
498 | 506 |
499 void PaintLayer::convertFromFlowThreadToVisualBoundingBoxInAncestor( | 507 void PaintLayer::convertFromFlowThreadToVisualBoundingBoxInAncestor( |
500 const PaintLayer* ancestorLayer, | 508 const PaintLayer* ancestorLayer, |
501 LayoutRect& rect) const { | 509 LayoutRect& rect) const { |
502 PaintLayer* paginationLayer = enclosingPaginationLayer(); | 510 PaintLayer* paginationLayer = enclosingPaginationLayer(); |
503 ASSERT(paginationLayer); | 511 ASSERT(paginationLayer); |
504 LayoutFlowThread* flowThread = | 512 LayoutFlowThread* flowThread = |
505 toLayoutFlowThread(paginationLayer->layoutObject()); | 513 toLayoutFlowThread(paginationLayer->layoutObject()); |
506 | 514 |
507 // First make the flow thread rectangle relative to the flow thread, not to |l
ayer|. | 515 // First make the flow thread rectangle relative to the flow thread, not to |
| 516 // |layer|. |
508 LayoutPoint offsetWithinPaginationLayer; | 517 LayoutPoint offsetWithinPaginationLayer; |
509 convertToLayerCoords(paginationLayer, offsetWithinPaginationLayer); | 518 convertToLayerCoords(paginationLayer, offsetWithinPaginationLayer); |
510 rect.moveBy(offsetWithinPaginationLayer); | 519 rect.moveBy(offsetWithinPaginationLayer); |
511 | 520 |
512 // Then make the rectangle visual, relative to the fragmentation context. Spli
t our box up into | 521 // Then make the rectangle visual, relative to the fragmentation context. |
513 // the actual fragment boxes that layout in the columns/pages and unite those
together to get | 522 // Split our box up into the actual fragment boxes that layout in the |
514 // our true bounding box. | 523 // columns/pages and unite those together to get our true bounding box. |
515 rect = flowThread->fragmentsBoundingBox(rect); | 524 rect = flowThread->fragmentsBoundingBox(rect); |
516 | 525 |
517 // Finally, make the visual rectangle relative to |ancestorLayer|. | 526 // Finally, make the visual rectangle relative to |ancestorLayer|. |
518 if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { | 527 if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { |
519 rect.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); | 528 rect.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); |
520 return; | 529 return; |
521 } | 530 } |
522 // The ancestor layer is inside the same pagination layer as |layer|, so we ne
ed to subtract | 531 // The ancestor layer is inside the same pagination layer as |layer|, so we |
523 // the visual distance from the ancestor layer to the pagination layer. | 532 // need to subtract the visual distance from the ancestor layer to the |
| 533 // pagination layer. |
524 rect.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer)); | 534 rect.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer)); |
525 } | 535 } |
526 | 536 |
527 void PaintLayer::updatePaginationRecursive(bool needsPaginationUpdate) { | 537 void PaintLayer::updatePaginationRecursive(bool needsPaginationUpdate) { |
528 if (m_rareData) | 538 if (m_rareData) |
529 m_rareData->enclosingPaginationLayer = nullptr; | 539 m_rareData->enclosingPaginationLayer = nullptr; |
530 | 540 |
531 if (layoutObject()->isLayoutFlowThread()) | 541 if (layoutObject()->isLayoutFlowThread()) |
532 needsPaginationUpdate = true; | 542 needsPaginationUpdate = true; |
533 | 543 |
534 if (needsPaginationUpdate) { | 544 if (needsPaginationUpdate) { |
535 // Each paginated layer has to paint on its own. There is no recurring into
child layers. Each | 545 // Each paginated layer has to paint on its own. There is no recurring into |
536 // layer has to be checked individually and genuinely know if it is going to
have to split | 546 // child layers. Each layer has to be checked individually and genuinely |
537 // itself up when painting only its contents (and not any other descendant l
ayers). We track an | 547 // know if it is going to have to split itself up when painting only its |
538 // enclosingPaginationLayer instead of using a simple bit, since we want to
be able to get back | 548 // contents (and not any other descendant layers). We track an |
539 // to that layer easily. | 549 // enclosingPaginationLayer instead of using a simple bit, since we want to |
| 550 // be able to get back to that layer easily. |
540 if (LayoutFlowThread* containingFlowThread = | 551 if (LayoutFlowThread* containingFlowThread = |
541 layoutObject()->flowThreadContainingBlock()) | 552 layoutObject()->flowThreadContainingBlock()) |
542 ensureRareData().enclosingPaginationLayer = containingFlowThread->layer(); | 553 ensureRareData().enclosingPaginationLayer = containingFlowThread->layer(); |
543 } | 554 } |
544 | 555 |
545 for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) | 556 for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) |
546 child->updatePaginationRecursive(needsPaginationUpdate); | 557 child->updatePaginationRecursive(needsPaginationUpdate); |
547 } | 558 } |
548 | 559 |
549 void PaintLayer::clearPaginationRecursive() { | 560 void PaintLayer::clearPaginationRecursive() { |
(...skipping 11 matching lines...) Expand all Loading... |
561 point.move(paintInvalidationLayer->compositedLayerMapping() | 572 point.move(paintInvalidationLayer->compositedLayerMapping() |
562 ->contentOffsetInCompositingLayer()); | 573 ->contentOffsetInCompositingLayer()); |
563 return; | 574 return; |
564 } | 575 } |
565 | 576 |
566 LayoutBoxModelObject* transformedAncestor = | 577 LayoutBoxModelObject* transformedAncestor = |
567 paintInvalidationLayer->enclosingTransformedAncestor()->layoutObject(); | 578 paintInvalidationLayer->enclosingTransformedAncestor()->layoutObject(); |
568 if (!transformedAncestor) | 579 if (!transformedAncestor) |
569 return; | 580 return; |
570 | 581 |
571 // |paintInvalidationContainer| may have a local 2D transform on it, so take t
hat into account when mapping into the space of the | 582 // |paintInvalidationContainer| may have a local 2D transform on it, so take |
572 // transformed ancestor. | 583 // that into account when mapping into the space of the transformed ancestor. |
573 point = paintInvalidationContainer.localToAncestorPoint(point, | 584 point = paintInvalidationContainer.localToAncestorPoint(point, |
574 transformedAncestor); | 585 transformedAncestor); |
575 | 586 |
576 point.moveBy(-paintInvalidationLayer->groupedMapping() | 587 point.moveBy(-paintInvalidationLayer->groupedMapping() |
577 ->squashingOffsetFromTransformedAncestor()); | 588 ->squashingOffsetFromTransformedAncestor()); |
578 } | 589 } |
579 | 590 |
580 void PaintLayer::mapRectInPaintInvalidationContainerToBacking( | 591 void PaintLayer::mapRectInPaintInvalidationContainerToBacking( |
581 const LayoutBoxModelObject& paintInvalidationContainer, | 592 const LayoutBoxModelObject& paintInvalidationContainer, |
582 LayoutRect& rect) { | 593 LayoutRect& rect) { |
583 PaintLayer* paintInvalidationLayer = paintInvalidationContainer.layer(); | 594 PaintLayer* paintInvalidationLayer = paintInvalidationContainer.layer(); |
584 if (!paintInvalidationLayer->groupedMapping()) { | 595 if (!paintInvalidationLayer->groupedMapping()) { |
585 rect.move(paintInvalidationLayer->compositedLayerMapping() | 596 rect.move(paintInvalidationLayer->compositedLayerMapping() |
586 ->contentOffsetInCompositingLayer()); | 597 ->contentOffsetInCompositingLayer()); |
587 return; | 598 return; |
588 } | 599 } |
589 | 600 |
590 LayoutBoxModelObject* transformedAncestor = | 601 LayoutBoxModelObject* transformedAncestor = |
591 paintInvalidationLayer->enclosingTransformedAncestor()->layoutObject(); | 602 paintInvalidationLayer->enclosingTransformedAncestor()->layoutObject(); |
592 if (!transformedAncestor) | 603 if (!transformedAncestor) |
593 return; | 604 return; |
594 | 605 |
595 // |paintInvalidationContainer| may have a local 2D transform on it, so take t
hat into account when mapping into the space of the | 606 // |paintInvalidationContainer| may have a local 2D transform on it, so take |
596 // transformed ancestor. | 607 // that into account when mapping into the space of the transformed ancestor. |
597 rect = | 608 rect = |
598 LayoutRect(paintInvalidationContainer | 609 LayoutRect(paintInvalidationContainer |
599 .localToAncestorQuad(FloatRect(rect), transformedAncestor) | 610 .localToAncestorQuad(FloatRect(rect), transformedAncestor) |
600 .boundingBox()); | 611 .boundingBox()); |
601 | 612 |
602 rect.moveBy(-paintInvalidationLayer->groupedMapping() | 613 rect.moveBy(-paintInvalidationLayer->groupedMapping() |
603 ->squashingOffsetFromTransformedAncestor()); | 614 ->squashingOffsetFromTransformedAncestor()); |
604 } | 615 } |
605 | 616 |
606 void PaintLayer::mapRectToPaintInvalidationBacking( | 617 void PaintLayer::mapRectToPaintInvalidationBacking( |
607 const LayoutObject& layoutObject, | 618 const LayoutObject& layoutObject, |
608 const LayoutBoxModelObject& paintInvalidationContainer, | 619 const LayoutBoxModelObject& paintInvalidationContainer, |
609 LayoutRect& rect) { | 620 LayoutRect& rect) { |
610 if (!paintInvalidationContainer.layer()->groupedMapping()) { | 621 if (!paintInvalidationContainer.layer()->groupedMapping()) { |
611 layoutObject.mapToVisualRectInAncestorSpace(&paintInvalidationContainer, | 622 layoutObject.mapToVisualRectInAncestorSpace(&paintInvalidationContainer, |
612 rect); | 623 rect); |
613 return; | 624 return; |
614 } | 625 } |
615 | 626 |
616 // This code adjusts the paint invalidation rectangle to be in the space of th
e transformed ancestor of the grouped (i.e. squashed) | 627 // This code adjusts the paint invalidation rectangle to be in the space of |
617 // layer. This is because all layers that squash together need to issue paint
invalidations w.r.t. a single container that is | 628 // the transformed ancestor of the grouped (i.e. squashed) layer. This is |
618 // an ancestor of all of them, in order to properly take into account any loca
l transforms etc. | 629 // because all layers that squash together need to issue paint invalidations |
619 // FIXME: remove this special-case code that works around the paint invalidati
on code structure. | 630 // w.r.t. a single container that is an ancestor of all of them, in order to |
| 631 // properly take into account any local transforms etc. |
| 632 // FIXME: remove this special-case code that works around the paint |
| 633 // invalidation code structure. |
620 layoutObject.mapToVisualRectInAncestorSpace(&paintInvalidationContainer, | 634 layoutObject.mapToVisualRectInAncestorSpace(&paintInvalidationContainer, |
621 rect); | 635 rect); |
622 | 636 |
623 mapRectInPaintInvalidationContainerToBacking(paintInvalidationContainer, | 637 mapRectInPaintInvalidationContainerToBacking(paintInvalidationContainer, |
624 rect); | 638 rect); |
625 } | 639 } |
626 | 640 |
627 void PaintLayer::dirtyVisibleContentStatus() { | 641 void PaintLayer::dirtyVisibleContentStatus() { |
628 compositor()->setNeedsUpdateDescendantDependentFlags(); | 642 compositor()->setNeedsUpdateDescendantDependentFlags(); |
629 m_isVisibleContentDirty = true; | 643 m_isVisibleContentDirty = true; |
630 if (parent()) | 644 if (parent()) |
631 parent()->dirtyAncestorChainVisibleDescendantStatus(); | 645 parent()->dirtyAncestorChainVisibleDescendantStatus(); |
632 // Non-self-painting layers paint into their ancestor layer, and count as part
of the "visible contents" of the parent, so we need to dirty it. | 646 // Non-self-painting layers paint into their ancestor layer, and count as part |
| 647 // of the "visible contents" of the parent, so we need to dirty it. |
633 if (!isSelfPaintingLayer()) | 648 if (!isSelfPaintingLayer()) |
634 parent()->dirtyVisibleContentStatus(); | 649 parent()->dirtyVisibleContentStatus(); |
635 } | 650 } |
636 | 651 |
637 void PaintLayer::potentiallyDirtyVisibleContentStatus(EVisibility visibility) { | 652 void PaintLayer::potentiallyDirtyVisibleContentStatus(EVisibility visibility) { |
638 if (m_isVisibleContentDirty) | 653 if (m_isVisibleContentDirty) |
639 return; | 654 return; |
640 if (hasVisibleContent() == (visibility == EVisibility::Visible)) | 655 if (hasVisibleContent() == (visibility == EVisibility::Visible)) |
641 return; | 656 return; |
642 dirtyVisibleContentStatus(); | 657 dirtyVisibleContentStatus(); |
643 } | 658 } |
644 | 659 |
645 void PaintLayer::dirtyAncestorChainVisibleDescendantStatus() { | 660 void PaintLayer::dirtyAncestorChainVisibleDescendantStatus() { |
646 compositor()->setNeedsUpdateDescendantDependentFlags(); | 661 compositor()->setNeedsUpdateDescendantDependentFlags(); |
647 | 662 |
648 for (PaintLayer* layer = this; layer; layer = layer->parent()) { | 663 for (PaintLayer* layer = this; layer; layer = layer->parent()) { |
649 if (layer->m_isVisibleDescendantDirty) | 664 if (layer->m_isVisibleDescendantDirty) |
650 break; | 665 break; |
651 layer->m_isVisibleDescendantDirty = true; | 666 layer->m_isVisibleDescendantDirty = true; |
652 } | 667 } |
653 } | 668 } |
654 | 669 |
655 // FIXME: this is quite brute-force. We could be more efficient if we were to | 670 // FIXME: this is quite brute-force. We could be more efficient if we were to |
656 // track state and update it as appropriate as changes are made in the layout tr
ee. | 671 // track state and update it as appropriate as changes are made in the layout |
| 672 // tree. |
657 void PaintLayer::updateScrollingStateAfterCompositingChange() { | 673 void PaintLayer::updateScrollingStateAfterCompositingChange() { |
658 TRACE_EVENT0("blink", | 674 TRACE_EVENT0("blink", |
659 "PaintLayer::updateScrollingStateAfterCompositingChange"); | 675 "PaintLayer::updateScrollingStateAfterCompositingChange"); |
660 m_isAllScrollingContentComposited = true; | 676 m_isAllScrollingContentComposited = true; |
661 for (LayoutObject* r = layoutObject()->slowFirstChild(); r; | 677 for (LayoutObject* r = layoutObject()->slowFirstChild(); r; |
662 r = r->nextSibling()) { | 678 r = r->nextSibling()) { |
663 if (!r->hasLayer()) { | 679 if (!r->hasLayer()) { |
664 m_isAllScrollingContentComposited = false; | 680 m_isAllScrollingContentComposited = false; |
665 return; | 681 return; |
666 } | 682 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 } | 757 } |
742 | 758 |
743 void PaintLayer::dirty3DTransformedDescendantStatus() { | 759 void PaintLayer::dirty3DTransformedDescendantStatus() { |
744 PaintLayerStackingNode* stackingNode = | 760 PaintLayerStackingNode* stackingNode = |
745 m_stackingNode->ancestorStackingContextNode(); | 761 m_stackingNode->ancestorStackingContextNode(); |
746 if (!stackingNode) | 762 if (!stackingNode) |
747 return; | 763 return; |
748 | 764 |
749 stackingNode->layer()->m_is3DTransformedDescendantDirty = true; | 765 stackingNode->layer()->m_is3DTransformedDescendantDirty = true; |
750 | 766 |
751 // This propagates up through preserve-3d hierarchies to the enclosing flatten
ing layer. | 767 // This propagates up through preserve-3d hierarchies to the enclosing |
752 // Note that preserves3D() creates stacking context, so we can just run up the
stacking containers. | 768 // flattening layer. Note that preserves3D() creates stacking context, so we |
| 769 // can just run up the stacking containers. |
753 while (stackingNode && stackingNode->layer()->preserves3D()) { | 770 while (stackingNode && stackingNode->layer()->preserves3D()) { |
754 stackingNode->layer()->m_is3DTransformedDescendantDirty = true; | 771 stackingNode->layer()->m_is3DTransformedDescendantDirty = true; |
755 stackingNode = stackingNode->ancestorStackingContextNode(); | 772 stackingNode = stackingNode->ancestorStackingContextNode(); |
756 } | 773 } |
757 } | 774 } |
758 | 775 |
759 // Return true if this layer or any preserve-3d descendants have 3d. | 776 // Return true if this layer or any preserve-3d descendants have 3d. |
760 bool PaintLayer::update3DTransformedDescendantStatus() { | 777 bool PaintLayer::update3DTransformedDescendantStatus() { |
761 if (m_is3DTransformedDescendantDirty) { | 778 if (m_is3DTransformedDescendantDirty) { |
762 m_has3DTransformedDescendant = false; | 779 m_has3DTransformedDescendant = false; |
763 | 780 |
764 m_stackingNode->updateZOrderLists(); | 781 m_stackingNode->updateZOrderLists(); |
765 | 782 |
766 // Transformed or preserve-3d descendants can only be in the z-order lists,
not | 783 // Transformed or preserve-3d descendants can only be in the z-order lists, |
767 // in the normal flow list, so we only need to check those. | 784 // not in the normal flow list, so we only need to check those. |
768 PaintLayerStackingNodeIterator iterator( | 785 PaintLayerStackingNodeIterator iterator( |
769 *m_stackingNode.get(), PositiveZOrderChildren | NegativeZOrderChildren); | 786 *m_stackingNode.get(), PositiveZOrderChildren | NegativeZOrderChildren); |
770 while (PaintLayerStackingNode* node = iterator.next()) | 787 while (PaintLayerStackingNode* node = iterator.next()) |
771 m_has3DTransformedDescendant |= | 788 m_has3DTransformedDescendant |= |
772 node->layer()->update3DTransformedDescendantStatus(); | 789 node->layer()->update3DTransformedDescendantStatus(); |
773 | 790 |
774 m_is3DTransformedDescendantDirty = false; | 791 m_is3DTransformedDescendantDirty = false; |
775 } | 792 } |
776 | 793 |
777 // If we live in a 3d hierarchy, then the layer at the root of that hierarchy
needs | 794 // If we live in a 3d hierarchy, then the layer at the root of that hierarchy |
778 // the m_has3DTransformedDescendant set. | 795 // needs the m_has3DTransformedDescendant set. |
779 if (preserves3D()) | 796 if (preserves3D()) |
780 return has3DTransform() || m_has3DTransformedDescendant; | 797 return has3DTransform() || m_has3DTransformedDescendant; |
781 | 798 |
782 return has3DTransform(); | 799 return has3DTransform(); |
783 } | 800 } |
784 | 801 |
785 void PaintLayer::updateLayerPosition() { | 802 void PaintLayer::updateLayerPosition() { |
786 LayoutPoint localPoint; | 803 LayoutPoint localPoint; |
787 | 804 |
788 if (layoutObject()->isInline() && layoutObject()->isLayoutInline()) { | 805 if (layoutObject()->isInline() && layoutObject()->isLayoutInline()) { |
(...skipping 22 matching lines...) Expand all Loading... |
811 // Put ourselves into the row coordinate space. | 828 // Put ourselves into the row coordinate space. |
812 localPoint.moveBy(-toLayoutBox(curr)->topLeftLocation()); | 829 localPoint.moveBy(-toLayoutBox(curr)->topLeftLocation()); |
813 } | 830 } |
814 } | 831 } |
815 | 832 |
816 // Subtract our parent's scroll offset. | 833 // Subtract our parent's scroll offset. |
817 if (PaintLayer* containingLayer = | 834 if (PaintLayer* containingLayer = |
818 layoutObject()->isOutOfFlowPositioned() | 835 layoutObject()->isOutOfFlowPositioned() |
819 ? containingLayerForOutOfFlowPositioned() | 836 ? containingLayerForOutOfFlowPositioned() |
820 : nullptr) { | 837 : nullptr) { |
821 // For positioned layers, we subtract out the enclosing positioned layer's s
croll offset. | 838 // For positioned layers, we subtract out the enclosing positioned layer's |
| 839 // scroll offset. |
822 if (containingLayer->layoutObject()->hasOverflowClip()) { | 840 if (containingLayer->layoutObject()->hasOverflowClip()) { |
823 IntSize offset = containingLayer->layoutBox()->scrolledContentOffset(); | 841 IntSize offset = containingLayer->layoutBox()->scrolledContentOffset(); |
824 localPoint -= offset; | 842 localPoint -= offset; |
825 } | 843 } |
826 | 844 |
827 if (containingLayer->layoutObject()->isInFlowPositioned() && | 845 if (containingLayer->layoutObject()->isInFlowPositioned() && |
828 containingLayer->layoutObject()->isLayoutInline()) { | 846 containingLayer->layoutObject()->isLayoutInline()) { |
829 LayoutSize offset = | 847 LayoutSize offset = |
830 toLayoutInline(containingLayer->layoutObject()) | 848 toLayoutInline(containingLayer->layoutObject()) |
831 ->offsetForInFlowPositionedInline(*toLayoutBox(layoutObject())); | 849 ->offsetForInFlowPositionedInline(*toLayoutBox(layoutObject())); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 | 895 |
878 return FloatPoint(floatValueForLength(style.perspectiveOriginX(), | 896 return FloatPoint(floatValueForLength(style.perspectiveOriginX(), |
879 borderBox.width().toFloat()), | 897 borderBox.width().toFloat()), |
880 floatValueForLength(style.perspectiveOriginY(), | 898 floatValueForLength(style.perspectiveOriginY(), |
881 borderBox.height().toFloat())); | 899 borderBox.height().toFloat())); |
882 } | 900 } |
883 | 901 |
884 PaintLayer* PaintLayer::containingLayerForOutOfFlowPositioned( | 902 PaintLayer* PaintLayer::containingLayerForOutOfFlowPositioned( |
885 const PaintLayer* ancestor, | 903 const PaintLayer* ancestor, |
886 bool* skippedAncestor) const { | 904 bool* skippedAncestor) const { |
887 ASSERT( | 905 // If we have specified an ancestor, surely the caller needs to know whether |
888 !ancestor || | 906 // we skipped it. |
889 skippedAncestor); // If we have specified an ancestor, surely the caller
needs to know whether we skipped it. | 907 ASSERT(!ancestor || skippedAncestor); |
890 if (skippedAncestor) | 908 if (skippedAncestor) |
891 *skippedAncestor = false; | 909 *skippedAncestor = false; |
892 if (layoutObject()->style()->position() == FixedPosition) { | 910 if (layoutObject()->style()->position() == FixedPosition) { |
893 PaintLayer* curr = parent(); | 911 PaintLayer* curr = parent(); |
894 while (curr && !curr->layoutObject()->canContainFixedPositionObjects()) { | 912 while (curr && !curr->layoutObject()->canContainFixedPositionObjects()) { |
895 if (skippedAncestor && curr == ancestor) | 913 if (skippedAncestor && curr == ancestor) |
896 *skippedAncestor = true; | 914 *skippedAncestor = true; |
897 curr = curr->parent(); | 915 curr = curr->parent(); |
898 } | 916 } |
899 | 917 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 stackingNode()->ancestorStackingContextNode()) | 953 stackingNode()->ancestorStackingContextNode()) |
936 return ancestorStackingNode->layer(); | 954 return ancestorStackingNode->layer(); |
937 return nullptr; | 955 return nullptr; |
938 } | 956 } |
939 | 957 |
940 bool PaintLayer::isPaintInvalidationContainer() const { | 958 bool PaintLayer::isPaintInvalidationContainer() const { |
941 return compositingState() == PaintsIntoOwnBacking || | 959 return compositingState() == PaintsIntoOwnBacking || |
942 compositingState() == PaintsIntoGroupedBacking; | 960 compositingState() == PaintsIntoGroupedBacking; |
943 } | 961 } |
944 | 962 |
945 // Note: enclosingCompositingLayer does not include squashed layers. Compositing
stacking children of squashed layers | 963 // Note: enclosingCompositingLayer does not include squashed layers. Compositing |
946 // receive graphics layers that are parented to the compositing ancestor of the
squashed layer. | 964 // stacking children of squashed layers receive graphics layers that are |
| 965 // parented to the compositing ancestor of the squashed layer. |
947 PaintLayer* PaintLayer::enclosingLayerWithCompositedLayerMapping( | 966 PaintLayer* PaintLayer::enclosingLayerWithCompositedLayerMapping( |
948 IncludeSelfOrNot includeSelf) const { | 967 IncludeSelfOrNot includeSelf) const { |
949 ASSERT(isAllowedToQueryCompositingState()); | 968 ASSERT(isAllowedToQueryCompositingState()); |
950 | 969 |
951 if ((includeSelf == IncludeSelf) && compositingState() != NotComposited && | 970 if ((includeSelf == IncludeSelf) && compositingState() != NotComposited && |
952 compositingState() != PaintsIntoGroupedBacking) | 971 compositingState() != PaintsIntoGroupedBacking) |
953 return const_cast<PaintLayer*>(this); | 972 return const_cast<PaintLayer*>(this); |
954 | 973 |
955 for (PaintLayer* curr = compositingContainer(); curr; | 974 for (PaintLayer* curr = compositingContainer(); curr; |
956 curr = curr->compositingContainer()) { | 975 curr = curr->compositingContainer()) { |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 return false; | 1124 return false; |
1106 } | 1125 } |
1107 | 1126 |
1108 static void expandClipRectForDescendantsAndReflection( | 1127 static void expandClipRectForDescendantsAndReflection( |
1109 LayoutRect& clipRect, | 1128 LayoutRect& clipRect, |
1110 const PaintLayer* layer, | 1129 const PaintLayer* layer, |
1111 const PaintLayer* rootLayer, | 1130 const PaintLayer* rootLayer, |
1112 PaintLayer::TransparencyClipBoxBehavior transparencyBehavior, | 1131 PaintLayer::TransparencyClipBoxBehavior transparencyBehavior, |
1113 const LayoutSize& subPixelAccumulation, | 1132 const LayoutSize& subPixelAccumulation, |
1114 GlobalPaintFlags globalPaintFlags) { | 1133 GlobalPaintFlags globalPaintFlags) { |
1115 // If we have a mask, then the clip is limited to the border box area (and the
re is | 1134 // If we have a mask, then the clip is limited to the border box area (and |
1116 // no need to examine child layers). | 1135 // there is no need to examine child layers). |
1117 if (!layer->layoutObject()->hasMask()) { | 1136 if (!layer->layoutObject()->hasMask()) { |
1118 // Note: we don't have to walk z-order lists since transparent elements alwa
ys establish | 1137 // Note: we don't have to walk z-order lists since transparent elements |
1119 // a stacking container. This means we can just walk the layer tree directly
. | 1138 // always establish a stacking container. This means we can just walk the |
| 1139 // layer tree directly. |
1120 for (PaintLayer* curr = layer->firstChild(); curr; | 1140 for (PaintLayer* curr = layer->firstChild(); curr; |
1121 curr = curr->nextSibling()) | 1141 curr = curr->nextSibling()) |
1122 clipRect.unite(PaintLayer::transparencyClipBox( | 1142 clipRect.unite(PaintLayer::transparencyClipBox( |
1123 curr, rootLayer, transparencyBehavior, | 1143 curr, rootLayer, transparencyBehavior, |
1124 PaintLayer::DescendantsOfTransparencyClipBox, subPixelAccumulation, | 1144 PaintLayer::DescendantsOfTransparencyClipBox, subPixelAccumulation, |
1125 globalPaintFlags)); | 1145 globalPaintFlags)); |
1126 } | 1146 } |
1127 | 1147 |
1128 // If we have a reflection, then we need to account for that when we push the
clip. Reflect our entire | 1148 // If we have a reflection, then we need to account for that when we push the |
1129 // current transparencyClipBox to catch all child layers. | 1149 // clip. Reflect our entire current transparencyClipBox to catch all child |
1130 // FIXME: Accelerated compositing will eventually want to do something smart h
ere to avoid incorporating this | 1150 // layers. |
1131 // size into the parent layer. | 1151 // FIXME: Accelerated compositing will eventually want to do something smart |
| 1152 // here to avoid incorporating this size into the parent layer. |
1132 if (layer->layoutObject()->hasReflection()) { | 1153 if (layer->layoutObject()->hasReflection()) { |
1133 LayoutPoint delta; | 1154 LayoutPoint delta; |
1134 layer->convertToLayerCoords(rootLayer, delta); | 1155 layer->convertToLayerCoords(rootLayer, delta); |
1135 clipRect.move(-delta.x(), -delta.y()); | 1156 clipRect.move(-delta.x(), -delta.y()); |
1136 clipRect.unite(layer->layoutBox()->reflectedRect(clipRect)); | 1157 clipRect.unite(layer->layoutBox()->reflectedRect(clipRect)); |
1137 clipRect.moveBy(delta); | 1158 clipRect.moveBy(delta); |
1138 } | 1159 } |
1139 } | 1160 } |
1140 | 1161 |
1141 LayoutRect PaintLayer::transparencyClipBox( | 1162 LayoutRect PaintLayer::transparencyClipBox( |
1142 const PaintLayer* layer, | 1163 const PaintLayer* layer, |
1143 const PaintLayer* rootLayer, | 1164 const PaintLayer* rootLayer, |
1144 TransparencyClipBoxBehavior transparencyBehavior, | 1165 TransparencyClipBoxBehavior transparencyBehavior, |
1145 TransparencyClipBoxMode transparencyMode, | 1166 TransparencyClipBoxMode transparencyMode, |
1146 const LayoutSize& subPixelAccumulation, | 1167 const LayoutSize& subPixelAccumulation, |
1147 GlobalPaintFlags globalPaintFlags) { | 1168 GlobalPaintFlags globalPaintFlags) { |
1148 // FIXME: Although this function completely ignores CSS-imposed clipping, we d
id already intersect with the | 1169 // FIXME: Although this function completely ignores CSS-imposed clipping, we |
1149 // paintDirtyRect, and that should cut down on the amount we have to paint. S
till it | 1170 // did already intersect with the paintDirtyRect, and that should cut down on |
1150 // would be better to respect clips. | 1171 // the amount we have to paint. Still it would be better to respect clips. |
1151 | 1172 |
1152 if (rootLayer != layer && | 1173 if (rootLayer != layer && |
1153 ((transparencyBehavior == PaintingTransparencyClipBox && | 1174 ((transparencyBehavior == PaintingTransparencyClipBox && |
1154 layer->paintsWithTransform(globalPaintFlags)) || | 1175 layer->paintsWithTransform(globalPaintFlags)) || |
1155 (transparencyBehavior == HitTestingTransparencyClipBox && | 1176 (transparencyBehavior == HitTestingTransparencyClipBox && |
1156 layer->hasTransformRelatedProperty()))) { | 1177 layer->hasTransformRelatedProperty()))) { |
1157 // The best we can do here is to use enclosed bounding boxes to establish a
"fuzzy" enough clip to encompass | 1178 // The best we can do here is to use enclosed bounding boxes to establish a |
1158 // the transformed layer and all of its children. | 1179 // "fuzzy" enough clip to encompass the transformed layer and all of its |
| 1180 // children. |
1159 const PaintLayer* paginationLayer = | 1181 const PaintLayer* paginationLayer = |
1160 transparencyMode == DescendantsOfTransparencyClipBox | 1182 transparencyMode == DescendantsOfTransparencyClipBox |
1161 ? layer->enclosingPaginationLayer() | 1183 ? layer->enclosingPaginationLayer() |
1162 : 0; | 1184 : 0; |
1163 const PaintLayer* rootLayerForTransform = | 1185 const PaintLayer* rootLayerForTransform = |
1164 paginationLayer ? paginationLayer : rootLayer; | 1186 paginationLayer ? paginationLayer : rootLayer; |
1165 LayoutPoint delta; | 1187 LayoutPoint delta; |
1166 layer->convertToLayerCoords(rootLayerForTransform, delta); | 1188 layer->convertToLayerCoords(rootLayerForTransform, delta); |
1167 | 1189 |
1168 delta.move(subPixelAccumulation); | 1190 delta.move(subPixelAccumulation); |
1169 IntPoint pixelSnappedDelta = roundedIntPoint(delta); | 1191 IntPoint pixelSnappedDelta = roundedIntPoint(delta); |
1170 TransformationMatrix transform; | 1192 TransformationMatrix transform; |
1171 transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y()); | 1193 transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y()); |
1172 if (layer->transform()) | 1194 if (layer->transform()) |
1173 transform = transform * *layer->transform(); | 1195 transform = transform * *layer->transform(); |
1174 | 1196 |
1175 // We don't use fragment boxes when collecting a transformed layer's boundin
g box, since it always | 1197 // We don't use fragment boxes when collecting a transformed layer's |
1176 // paints unfragmented. | 1198 // bounding box, since it always paints unfragmented. |
1177 LayoutRect clipRect = layer->physicalBoundingBox(LayoutPoint()); | 1199 LayoutRect clipRect = layer->physicalBoundingBox(LayoutPoint()); |
1178 expandClipRectForDescendantsAndReflection( | 1200 expandClipRectForDescendantsAndReflection( |
1179 clipRect, layer, layer, transparencyBehavior, subPixelAccumulation, | 1201 clipRect, layer, layer, transparencyBehavior, subPixelAccumulation, |
1180 globalPaintFlags); | 1202 globalPaintFlags); |
1181 LayoutRect result = enclosingLayoutRect( | 1203 LayoutRect result = enclosingLayoutRect( |
1182 transform.mapRect(layer->mapRectForFilter(FloatRect(clipRect)))); | 1204 transform.mapRect(layer->mapRectForFilter(FloatRect(clipRect)))); |
1183 if (!paginationLayer) | 1205 if (!paginationLayer) |
1184 return result; | 1206 return result; |
1185 | 1207 |
1186 // We have to break up the transformed extent across our columns. | 1208 // We have to break up the transformed extent across our columns. |
1187 // Split our box up into the actual fragment boxes that layout in the column
s/pages and unite those together to | 1209 // Split our box up into the actual fragment boxes that layout in the |
1188 // get our true bounding box. | 1210 // columns/pages and unite those together to get our true bounding box. |
1189 LayoutFlowThread* enclosingFlowThread = | 1211 LayoutFlowThread* enclosingFlowThread = |
1190 toLayoutFlowThread(paginationLayer->layoutObject()); | 1212 toLayoutFlowThread(paginationLayer->layoutObject()); |
1191 result = enclosingFlowThread->fragmentsBoundingBox(result); | 1213 result = enclosingFlowThread->fragmentsBoundingBox(result); |
1192 | 1214 |
1193 LayoutPoint rootLayerDelta; | 1215 LayoutPoint rootLayerDelta; |
1194 paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta); | 1216 paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta); |
1195 result.moveBy(rootLayerDelta); | 1217 result.moveBy(rootLayerDelta); |
1196 return result; | 1218 return result; |
1197 } | 1219 } |
1198 | 1220 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1238 if (beforeChild) { | 1260 if (beforeChild) { |
1239 beforeChild->setPreviousSibling(child); | 1261 beforeChild->setPreviousSibling(child); |
1240 child->setNextSibling(beforeChild); | 1262 child->setNextSibling(beforeChild); |
1241 ASSERT(beforeChild != child); | 1263 ASSERT(beforeChild != child); |
1242 } else { | 1264 } else { |
1243 setLastChild(child); | 1265 setLastChild(child); |
1244 } | 1266 } |
1245 | 1267 |
1246 child->m_parent = this; | 1268 child->m_parent = this; |
1247 | 1269 |
1248 // The ancestor overflow layer is calculated during compositing inputs update
and should not be set yet. | 1270 // The ancestor overflow layer is calculated during compositing inputs update |
| 1271 // and should not be set yet. |
1249 ASSERT(!child->ancestorOverflowLayer()); | 1272 ASSERT(!child->ancestorOverflowLayer()); |
1250 | 1273 |
1251 setNeedsCompositingInputsUpdate(); | 1274 setNeedsCompositingInputsUpdate(); |
1252 | 1275 |
1253 if (!child->stackingNode()->isStacked() && | 1276 if (!child->stackingNode()->isStacked() && |
1254 !layoutObject()->documentBeingDestroyed()) | 1277 !layoutObject()->documentBeingDestroyed()) |
1255 compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree); | 1278 compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree); |
1256 | 1279 |
1257 if (child->stackingNode()->isStacked() || child->firstChild()) { | 1280 if (child->stackingNode()->isStacked() || child->firstChild()) { |
1258 // Dirty the z-order list in which we are contained. The ancestorStackingCon
textNode() can be null in the | 1281 // Dirty the z-order list in which we are contained. The |
1259 // case where we're building up generated content layers. This is ok, since
the lists will start | 1282 // ancestorStackingContextNode() can be null in the case where we're |
1260 // off dirty in that case anyway. | 1283 // building up generated content layers. This is ok, since the lists will |
| 1284 // start off dirty in that case anyway. |
1261 child->stackingNode()->dirtyStackingContextZOrderLists(); | 1285 child->stackingNode()->dirtyStackingContextZOrderLists(); |
1262 } | 1286 } |
1263 | 1287 |
1264 // Non-self-painting children paint into this layer, so the visible contents s
tatus of this layer is affected. | 1288 // Non-self-painting children paint into this layer, so the visible contents |
| 1289 // status of this layer is affected. |
1265 if (!child->isSelfPaintingLayer()) | 1290 if (!child->isSelfPaintingLayer()) |
1266 dirtyVisibleContentStatus(); | 1291 dirtyVisibleContentStatus(); |
1267 | 1292 |
1268 dirtyAncestorChainVisibleDescendantStatus(); | 1293 dirtyAncestorChainVisibleDescendantStatus(); |
1269 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); | 1294 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); |
1270 | 1295 |
1271 child->setNeedsRepaint(); | 1296 child->setNeedsRepaint(); |
1272 | 1297 |
1273 child->updateDescendantDependentFlags(); | 1298 child->updateDescendantDependentFlags(); |
1274 } | 1299 } |
1275 | 1300 |
1276 PaintLayer* PaintLayer::removeChild(PaintLayer* oldChild) { | 1301 PaintLayer* PaintLayer::removeChild(PaintLayer* oldChild) { |
1277 if (oldChild->previousSibling()) | 1302 if (oldChild->previousSibling()) |
1278 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); | 1303 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); |
1279 if (oldChild->nextSibling()) | 1304 if (oldChild->nextSibling()) |
1280 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()); | 1305 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()); |
1281 | 1306 |
1282 if (m_first == oldChild) | 1307 if (m_first == oldChild) |
1283 m_first = oldChild->nextSibling(); | 1308 m_first = oldChild->nextSibling(); |
1284 if (m_last == oldChild) | 1309 if (m_last == oldChild) |
1285 m_last = oldChild->previousSibling(); | 1310 m_last = oldChild->previousSibling(); |
1286 | 1311 |
1287 if (!oldChild->stackingNode()->isStacked() && | 1312 if (!oldChild->stackingNode()->isStacked() && |
1288 !layoutObject()->documentBeingDestroyed()) | 1313 !layoutObject()->documentBeingDestroyed()) |
1289 compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree); | 1314 compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree); |
1290 | 1315 |
1291 if (oldChild->stackingNode()->isStacked() || oldChild->firstChild()) { | 1316 if (oldChild->stackingNode()->isStacked() || oldChild->firstChild()) { |
1292 // Dirty the z-order list in which we are contained. When called via the | 1317 // Dirty the z-order list in which we are contained. When called via the |
1293 // reattachment process in removeOnlyThisLayer, the layer may already be dis
connected | 1318 // reattachment process in removeOnlyThisLayer, the layer may already be |
1294 // from the main layer tree, so we need to null-check the | 1319 // disconnected from the main layer tree, so we need to null-check the |
1295 // |stackingContext| value. | 1320 // |stackingContext| value. |
1296 oldChild->stackingNode()->dirtyStackingContextZOrderLists(); | 1321 oldChild->stackingNode()->dirtyStackingContextZOrderLists(); |
1297 } | 1322 } |
1298 | 1323 |
1299 if (layoutObject()->style()->visibility() != EVisibility::Visible) | 1324 if (layoutObject()->style()->visibility() != EVisibility::Visible) |
1300 dirtyVisibleContentStatus(); | 1325 dirtyVisibleContentStatus(); |
1301 | 1326 |
1302 oldChild->setPreviousSibling(0); | 1327 oldChild->setPreviousSibling(0); |
1303 oldChild->setNextSibling(0); | 1328 oldChild->setNextSibling(0); |
1304 oldChild->m_parent = 0; | 1329 oldChild->m_parent = 0; |
(...skipping 19 matching lines...) Expand all Loading... |
1324 | 1349 |
1325 void PaintLayer::removeOnlyThisLayerAfterStyleChange() { | 1350 void PaintLayer::removeOnlyThisLayerAfterStyleChange() { |
1326 if (!m_parent) | 1351 if (!m_parent) |
1327 return; | 1352 return; |
1328 | 1353 |
1329 bool didSetPaintInvalidation = false; | 1354 bool didSetPaintInvalidation = false; |
1330 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 1355 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
1331 DisableCompositingQueryAsserts | 1356 DisableCompositingQueryAsserts |
1332 disabler; // We need the current compositing status. | 1357 disabler; // We need the current compositing status. |
1333 if (isPaintInvalidationContainer()) { | 1358 if (isPaintInvalidationContainer()) { |
1334 // Our children will be reparented and contained by a new paint invalidati
on container, | 1359 // Our children will be reparented and contained by a new paint |
1335 // so need paint invalidation. CompositingUpdate can't see this layer (whi
ch has been | 1360 // invalidation container, so need paint invalidation. CompositingUpdate |
1336 // removed) so won't do this for us. | 1361 // can't see this layer (which has been removed) so won't do this for us. |
1337 DisablePaintInvalidationStateAsserts disabler; | 1362 DisablePaintInvalidationStateAsserts disabler; |
1338 ObjectPaintInvalidator(*layoutObject()) | 1363 ObjectPaintInvalidator(*layoutObject()) |
1339 .invalidatePaintIncludingNonCompositingDescendants(); | 1364 .invalidatePaintIncludingNonCompositingDescendants(); |
1340 layoutObject() | 1365 layoutObject() |
1341 ->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants()
; | 1366 ->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants()
; |
1342 didSetPaintInvalidation = true; | 1367 didSetPaintInvalidation = true; |
1343 } | 1368 } |
1344 } | 1369 } |
1345 | 1370 |
1346 if (!didSetPaintInvalidation && isSelfPaintingLayer()) { | 1371 if (!didSetPaintInvalidation && isSelfPaintingLayer()) { |
(...skipping 27 matching lines...) Expand all Loading... |
1374 if (!m_parent && layoutObject()->parent()) { | 1399 if (!m_parent && layoutObject()->parent()) { |
1375 // We need to connect ourselves when our layoutObject() has a parent. | 1400 // We need to connect ourselves when our layoutObject() has a parent. |
1376 // Find our enclosingLayer and add ourselves. | 1401 // Find our enclosingLayer and add ourselves. |
1377 PaintLayer* parentLayer = layoutObject()->parent()->enclosingLayer(); | 1402 PaintLayer* parentLayer = layoutObject()->parent()->enclosingLayer(); |
1378 ASSERT(parentLayer); | 1403 ASSERT(parentLayer); |
1379 PaintLayer* beforeChild = | 1404 PaintLayer* beforeChild = |
1380 layoutObject()->parent()->findNextLayer(parentLayer, layoutObject()); | 1405 layoutObject()->parent()->findNextLayer(parentLayer, layoutObject()); |
1381 parentLayer->addChild(this, beforeChild); | 1406 parentLayer->addChild(this, beforeChild); |
1382 } | 1407 } |
1383 | 1408 |
1384 // Remove all descendant layers from the hierarchy and add them to the new pos
ition. | 1409 // Remove all descendant layers from the hierarchy and add them to the new |
| 1410 // position. |
1385 for (LayoutObject* curr = layoutObject()->slowFirstChild(); curr; | 1411 for (LayoutObject* curr = layoutObject()->slowFirstChild(); curr; |
1386 curr = curr->nextSibling()) | 1412 curr = curr->nextSibling()) |
1387 curr->moveLayers(m_parent, this); | 1413 curr->moveLayers(m_parent, this); |
1388 | 1414 |
1389 // If the previous paint invalidation container is not a stacking context and
this object is | 1415 // If the previous paint invalidation container is not a stacking context and |
1390 // stacked content, creating this layer may cause this object and its descenda
nts to change | 1416 // this object is stacked content, creating this layer may cause this object |
1391 // paint invalidation container. | 1417 // and its descendants to change paint invalidation container. |
1392 bool didSetPaintInvalidation = false; | 1418 bool didSetPaintInvalidation = false; |
1393 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | 1419 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && |
1394 !layoutObject()->isLayoutView() && layoutObject()->isRooted() && | 1420 !layoutObject()->isLayoutView() && layoutObject()->isRooted() && |
1395 layoutObject()->styleRef().isStacked()) { | 1421 layoutObject()->styleRef().isStacked()) { |
1396 const LayoutBoxModelObject& previousPaintInvalidationContainer = | 1422 const LayoutBoxModelObject& previousPaintInvalidationContainer = |
1397 layoutObject()->parent()->containerForPaintInvalidation(); | 1423 layoutObject()->parent()->containerForPaintInvalidation(); |
1398 if (!previousPaintInvalidationContainer.styleRef().isStackingContext()) { | 1424 if (!previousPaintInvalidationContainer.styleRef().isStackingContext()) { |
1399 ObjectPaintInvalidator(*layoutObject()) | 1425 ObjectPaintInvalidator(*layoutObject()) |
1400 .invalidatePaintIncludingNonSelfPaintingLayerDescendants( | 1426 .invalidatePaintIncludingNonSelfPaintingLayerDescendants( |
1401 previousPaintInvalidationContainer); | 1427 previousPaintInvalidationContainer); |
(...skipping 18 matching lines...) Expand all Loading... |
1420 const PaintLayer* layer, | 1446 const PaintLayer* layer, |
1421 const PaintLayer* ancestorLayer, | 1447 const PaintLayer* ancestorLayer, |
1422 LayoutPoint& location) { | 1448 LayoutPoint& location) { |
1423 ASSERT(ancestorLayer != layer); | 1449 ASSERT(ancestorLayer != layer); |
1424 | 1450 |
1425 const LayoutBoxModelObject* layoutObject = layer->layoutObject(); | 1451 const LayoutBoxModelObject* layoutObject = layer->layoutObject(); |
1426 EPosition position = layoutObject->style()->position(); | 1452 EPosition position = layoutObject->style()->position(); |
1427 | 1453 |
1428 if (position == FixedPosition && | 1454 if (position == FixedPosition && |
1429 (!ancestorLayer || ancestorLayer == layoutObject->view()->layer())) { | 1455 (!ancestorLayer || ancestorLayer == layoutObject->view()->layer())) { |
1430 // If the fixed layer's container is the root, just add in the offset of the
view. We can obtain this by calling | 1456 // If the fixed layer's container is the root, just add in the offset of the |
1431 // localToAbsolute() on the LayoutView. | 1457 // view. We can obtain this by calling localToAbsolute() on the LayoutView. |
1432 FloatPoint absPos = layoutObject->localToAbsolute(); | 1458 FloatPoint absPos = layoutObject->localToAbsolute(); |
1433 location += LayoutSize(absPos.x(), absPos.y()); | 1459 location += LayoutSize(absPos.x(), absPos.y()); |
1434 return ancestorLayer; | 1460 return ancestorLayer; |
1435 } | 1461 } |
1436 | 1462 |
1437 PaintLayer* parentLayer; | 1463 PaintLayer* parentLayer; |
1438 if (position == AbsolutePosition || position == FixedPosition) { | 1464 if (position == AbsolutePosition || position == FixedPosition) { |
1439 bool foundAncestorFirst; | 1465 bool foundAncestorFirst; |
1440 parentLayer = layer->containingLayerForOutOfFlowPositioned( | 1466 parentLayer = layer->containingLayerForOutOfFlowPositioned( |
1441 ancestorLayer, &foundAncestorFirst); | 1467 ancestorLayer, &foundAncestorFirst); |
1442 | 1468 |
1443 if (foundAncestorFirst) { | 1469 if (foundAncestorFirst) { |
1444 // Found ancestorLayer before the container of the out-of-flow object, so
compute offset | 1470 // Found ancestorLayer before the container of the out-of-flow object, so |
1445 // of both relative to the container and subtract. | 1471 // compute offset of both relative to the container and subtract. |
1446 | 1472 |
1447 LayoutPoint thisCoords; | 1473 LayoutPoint thisCoords; |
1448 layer->convertToLayerCoords(parentLayer, thisCoords); | 1474 layer->convertToLayerCoords(parentLayer, thisCoords); |
1449 | 1475 |
1450 LayoutPoint ancestorCoords; | 1476 LayoutPoint ancestorCoords; |
1451 ancestorLayer->convertToLayerCoords(parentLayer, ancestorCoords); | 1477 ancestorLayer->convertToLayerCoords(parentLayer, ancestorCoords); |
1452 | 1478 |
1453 location += (thisCoords - ancestorCoords); | 1479 location += (thisCoords - ancestorCoords); |
1454 return ancestorLayer; | 1480 return ancestorLayer; |
1455 } | 1481 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1503 LayoutFlowThread* flowThread = | 1529 LayoutFlowThread* flowThread = |
1504 toLayoutFlowThread(paginationLayer->layoutObject()); | 1530 toLayoutFlowThread(paginationLayer->layoutObject()); |
1505 convertToLayerCoords(paginationLayer, offset); | 1531 convertToLayerCoords(paginationLayer, offset); |
1506 offset = flowThread->flowThreadPointToVisualPoint(offset); | 1532 offset = flowThread->flowThreadPointToVisualPoint(offset); |
1507 if (ancestorLayer == paginationLayer) | 1533 if (ancestorLayer == paginationLayer) |
1508 return offset; | 1534 return offset; |
1509 | 1535 |
1510 if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { | 1536 if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { |
1511 offset.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); | 1537 offset.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); |
1512 } else { | 1538 } else { |
1513 // The ancestor layer is also inside the pagination layer, so we need to sub
tract the visual | 1539 // The ancestor layer is also inside the pagination layer, so we need to |
1514 // distance from the ancestor layer to the pagination layer. | 1540 // subtract the visual distance from the ancestor layer to the pagination |
| 1541 // layer. |
1515 offset.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer)); | 1542 offset.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer)); |
1516 } | 1543 } |
1517 return offset; | 1544 return offset; |
1518 } | 1545 } |
1519 | 1546 |
1520 void PaintLayer::didUpdateNeedsCompositedScrolling() { | 1547 void PaintLayer::didUpdateNeedsCompositedScrolling() { |
1521 bool wasSelfPaintingLayer = isSelfPaintingLayer(); | 1548 bool wasSelfPaintingLayer = isSelfPaintingLayer(); |
1522 updateSelfPaintingLayer(); | 1549 updateSelfPaintingLayer(); |
1523 | 1550 |
1524 // If the floating object becomes non-self-painting, so some ancestor should p
aint it; | 1551 // If the floating object becomes non-self-painting, so some ancestor should |
1525 // if it becomes self-painting, it should paint itself and no ancestor should
paint it. | 1552 // paint it; if it becomes self-painting, it should paint itself and no |
| 1553 // ancestor should paint it. |
1526 if (wasSelfPaintingLayer != isSelfPaintingLayer() && | 1554 if (wasSelfPaintingLayer != isSelfPaintingLayer() && |
1527 m_layoutObject->isFloating()) | 1555 m_layoutObject->isFloating()) |
1528 LayoutBlockFlow::setAncestorShouldPaintFloatingObject(*layoutBox()); | 1556 LayoutBlockFlow::setAncestorShouldPaintFloatingObject(*layoutBox()); |
1529 } | 1557 } |
1530 | 1558 |
1531 void PaintLayer::updateStackingNode() { | 1559 void PaintLayer::updateStackingNode() { |
1532 ASSERT(!m_stackingNode); | 1560 ASSERT(!m_stackingNode); |
1533 if (requiresStackingNode()) | 1561 if (requiresStackingNode()) |
1534 m_stackingNode = wrapUnique(new PaintLayerStackingNode(this)); | 1562 m_stackingNode = wrapUnique(new PaintLayerStackingNode(this)); |
1535 else | 1563 else |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1600 fragments, rootLayer, dirtyRect, clipRectsCacheSlot, | 1628 fragments, rootLayer, dirtyRect, clipRectsCacheSlot, |
1601 overlayScrollbarClipBehavior, respectOverflowClip, offsetFromRoot, | 1629 overlayScrollbarClipBehavior, respectOverflowClip, offsetFromRoot, |
1602 subPixelAccumulation); | 1630 subPixelAccumulation); |
1603 return; | 1631 return; |
1604 } | 1632 } |
1605 | 1633 |
1606 // Compute our offset within the enclosing pagination layer. | 1634 // Compute our offset within the enclosing pagination layer. |
1607 LayoutPoint offsetWithinPaginatedLayer; | 1635 LayoutPoint offsetWithinPaginatedLayer; |
1608 convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginatedLayer); | 1636 convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginatedLayer); |
1609 | 1637 |
1610 // Calculate clip rects relative to the enclosingPaginationLayer. The purpose
of this call is to determine our bounds clipped to intermediate | 1638 // Calculate clip rects relative to the enclosingPaginationLayer. The purpose |
1611 // layers between us and the pagination context. It's important to minimize th
e number of fragments we need to create and this helps with that. | 1639 // of this call is to determine our bounds clipped to intermediate layers |
| 1640 // between us and the pagination context. It's important to minimize the |
| 1641 // number of fragments we need to create and this helps with that. |
1612 ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), | 1642 ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), |
1613 clipRectsCacheSlot, | 1643 clipRectsCacheSlot, |
1614 overlayScrollbarClipBehavior); | 1644 overlayScrollbarClipBehavior); |
1615 if (respectOverflowClip == IgnoreOverflowClip) | 1645 if (respectOverflowClip == IgnoreOverflowClip) |
1616 paginationClipRectsContext.setIgnoreOverflowClip(); | 1646 paginationClipRectsContext.setIgnoreOverflowClip(); |
1617 LayoutRect layerBoundsInFlowThread; | 1647 LayoutRect layerBoundsInFlowThread; |
1618 ClipRect backgroundRectInFlowThread; | 1648 ClipRect backgroundRectInFlowThread; |
1619 ClipRect foregroundRectInFlowThread; | 1649 ClipRect foregroundRectInFlowThread; |
1620 clipper().calculateRects( | 1650 clipper().calculateRects( |
1621 paginationClipRectsContext, LayoutRect(LayoutRect::infiniteIntRect()), | 1651 paginationClipRectsContext, LayoutRect(LayoutRect::infiniteIntRect()), |
1622 layerBoundsInFlowThread, backgroundRectInFlowThread, | 1652 layerBoundsInFlowThread, backgroundRectInFlowThread, |
1623 foregroundRectInFlowThread, &offsetWithinPaginatedLayer); | 1653 foregroundRectInFlowThread, &offsetWithinPaginatedLayer); |
1624 | 1654 |
1625 // Take our bounding box within the flow thread and clip it. | 1655 // Take our bounding box within the flow thread and clip it. |
1626 LayoutRect layerBoundingBoxInFlowThread = | 1656 LayoutRect layerBoundingBoxInFlowThread = |
1627 layerBoundingBox ? *layerBoundingBox | 1657 layerBoundingBox ? *layerBoundingBox |
1628 : physicalBoundingBox(offsetWithinPaginatedLayer); | 1658 : physicalBoundingBox(offsetWithinPaginatedLayer); |
1629 layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect()); | 1659 layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect()); |
1630 | 1660 |
1631 LayoutFlowThread* enclosingFlowThread = | 1661 LayoutFlowThread* enclosingFlowThread = |
1632 toLayoutFlowThread(enclosingPaginationLayer()->layoutObject()); | 1662 toLayoutFlowThread(enclosingPaginationLayer()->layoutObject()); |
1633 LayoutPoint | 1663 // Visual offset from the root layer to the nearest fragmentation context. |
1634 offsetOfPaginationLayerFromRoot; // Visual offset from the root layer to
the nearest fragmentation context. | 1664 LayoutPoint offsetOfPaginationLayerFromRoot; |
1635 bool rootLayerIsInsidePaginationLayer = | 1665 bool rootLayerIsInsidePaginationLayer = |
1636 rootLayer->enclosingPaginationLayer() == enclosingPaginationLayer(); | 1666 rootLayer->enclosingPaginationLayer() == enclosingPaginationLayer(); |
1637 if (rootLayerIsInsidePaginationLayer) { | 1667 if (rootLayerIsInsidePaginationLayer) { |
1638 // The root layer is in the same fragmentation context as this layer, so we
need to look | 1668 // The root layer is in the same fragmentation context as this layer, so we |
1639 // inside it and subtract the offset between the fragmentation context and t
he root layer. | 1669 // need to look inside it and subtract the offset between the fragmentation |
| 1670 // context and the root layer. |
1640 offsetOfPaginationLayerFromRoot = | 1671 offsetOfPaginationLayerFromRoot = |
1641 -rootLayer->visualOffsetFromAncestor(enclosingPaginationLayer()); | 1672 -rootLayer->visualOffsetFromAncestor(enclosingPaginationLayer()); |
1642 } else { | 1673 } else { |
1643 offsetOfPaginationLayerFromRoot = | 1674 offsetOfPaginationLayerFromRoot = |
1644 enclosingPaginationLayer()->visualOffsetFromAncestor(rootLayer); | 1675 enclosingPaginationLayer()->visualOffsetFromAncestor(rootLayer); |
1645 } | 1676 } |
1646 // Make the dirty rect relative to the fragmentation context (multicol contain
er, etc.). | 1677 // Make the dirty rect relative to the fragmentation context (multicol |
| 1678 // container, etc.). |
1647 LayoutRect dirtyRectInMulticolContainer(dirtyRect); | 1679 LayoutRect dirtyRectInMulticolContainer(dirtyRect); |
1648 dirtyRectInMulticolContainer.move(enclosingPaginationLayer()->location() - | 1680 dirtyRectInMulticolContainer.move(enclosingPaginationLayer()->location() - |
1649 offsetOfPaginationLayerFromRoot); | 1681 offsetOfPaginationLayerFromRoot); |
1650 | 1682 |
1651 // Slice the layer into fragments. Each fragment needs to be processed (e.g. p
ainted) | 1683 // Slice the layer into fragments. Each fragment needs to be processed (e.g. |
1652 // separately. We pass enough information to walk a minimal number of fragment
s based on the | 1684 // painted) separately. We pass enough information to walk a minimal number of |
1653 // pages/columns that intersect the actual dirtyRect as well as the pages/colu
mns that | 1685 // fragments based on the pages/columns that intersect the actual dirtyRect as |
1654 // intersect our layer's bounding box. | 1686 // well as the pages/columns that intersect our layer's bounding box. |
1655 FragmentainerIterator iterator(*enclosingFlowThread, | 1687 FragmentainerIterator iterator(*enclosingFlowThread, |
1656 layerBoundingBoxInFlowThread, | 1688 layerBoundingBoxInFlowThread, |
1657 dirtyRectInMulticolContainer); | 1689 dirtyRectInMulticolContainer); |
1658 if (iterator.atEnd()) | 1690 if (iterator.atEnd()) |
1659 return; | 1691 return; |
1660 | 1692 |
1661 // Get the parent clip rects of the pagination layer, since we need to interse
ct with that when painting column contents. | 1693 // Get the parent clip rects of the pagination layer, since we need to |
| 1694 // intersect with that when painting column contents. |
1662 ClipRect ancestorClipRect = dirtyRect; | 1695 ClipRect ancestorClipRect = dirtyRect; |
1663 if (const PaintLayer* paginationParentLayer = | 1696 if (const PaintLayer* paginationParentLayer = |
1664 enclosingPaginationLayer()->parent()) { | 1697 enclosingPaginationLayer()->parent()) { |
1665 const PaintLayer* ancestorLayer = | 1698 const PaintLayer* ancestorLayer = |
1666 rootLayerIsInsidePaginationLayer ? paginationParentLayer : rootLayer; | 1699 rootLayerIsInsidePaginationLayer ? paginationParentLayer : rootLayer; |
1667 ClipRectsContext clipRectsContext(ancestorLayer, clipRectsCacheSlot, | 1700 ClipRectsContext clipRectsContext(ancestorLayer, clipRectsCacheSlot, |
1668 overlayScrollbarClipBehavior); | 1701 overlayScrollbarClipBehavior); |
1669 if (respectOverflowClip == IgnoreOverflowClip) | 1702 if (respectOverflowClip == IgnoreOverflowClip) |
1670 clipRectsContext.setIgnoreOverflowClip(); | 1703 clipRectsContext.setIgnoreOverflowClip(); |
1671 ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipRect( | 1704 ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipRect( |
1672 clipRectsContext); | 1705 clipRectsContext); |
1673 if (rootLayerIsInsidePaginationLayer) | 1706 if (rootLayerIsInsidePaginationLayer) |
1674 ancestorClipRect.moveBy( | 1707 ancestorClipRect.moveBy( |
1675 -rootLayer->visualOffsetFromAncestor(ancestorLayer)); | 1708 -rootLayer->visualOffsetFromAncestor(ancestorLayer)); |
1676 ancestorClipRect.intersect(dirtyRect); | 1709 ancestorClipRect.intersect(dirtyRect); |
1677 } | 1710 } |
1678 | 1711 |
1679 const LayoutSize subPixelAccumulationIfNeeded = | 1712 const LayoutSize subPixelAccumulationIfNeeded = |
1680 offsetFromRoot ? subPixelAccumulation : LayoutSize(); | 1713 offsetFromRoot ? subPixelAccumulation : LayoutSize(); |
1681 for (; !iterator.atEnd(); iterator.advance()) { | 1714 for (; !iterator.atEnd(); iterator.advance()) { |
1682 PaintLayerFragment fragment; | 1715 PaintLayerFragment fragment; |
1683 fragment.paginationOffset = toLayoutPoint(iterator.paginationOffset()); | 1716 fragment.paginationOffset = toLayoutPoint(iterator.paginationOffset()); |
1684 fragment.paginationClip = iterator.clipRectInFlowThread(); | 1717 fragment.paginationClip = iterator.clipRectInFlowThread(); |
1685 | 1718 |
1686 // Set our four rects with all clipping applied that was internal to the flo
w thread. | 1719 // Set our four rects with all clipping applied that was internal to the |
| 1720 // flow thread. |
1687 fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, | 1721 fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, |
1688 foregroundRectInFlowThread); | 1722 foregroundRectInFlowThread); |
1689 | 1723 |
1690 // Shift to the root-relative physical position used when painting the flow
thread in this fragment. | 1724 // Shift to the root-relative physical position used when painting the flow |
| 1725 // thread in this fragment. |
1691 fragment.moveBy(fragment.paginationOffset + | 1726 fragment.moveBy(fragment.paginationOffset + |
1692 offsetOfPaginationLayerFromRoot + | 1727 offsetOfPaginationLayerFromRoot + |
1693 subPixelAccumulationIfNeeded); | 1728 subPixelAccumulationIfNeeded); |
1694 | 1729 |
1695 // Intersect the fragment with our ancestor's background clip so that e.g.,
columns in an overflow:hidden block are | 1730 // Intersect the fragment with our ancestor's background clip so that e.g., |
1696 // properly clipped by the overflow. | 1731 // columns in an overflow:hidden block are properly clipped by the overflow. |
1697 fragment.intersect(ancestorClipRect.rect()); | 1732 fragment.intersect(ancestorClipRect.rect()); |
1698 | 1733 |
1699 // Now intersect with our pagination clip. This will typically mean we're ju
st intersecting the dirty rect with the column | 1734 // Now intersect with our pagination clip. This will typically mean we're |
1700 // clip, so the column clip ends up being all we apply. | 1735 // just intersecting the dirty rect with the column clip, so the column clip |
| 1736 // ends up being all we apply. |
1701 fragment.intersect(fragment.paginationClip); | 1737 fragment.intersect(fragment.paginationClip); |
1702 | 1738 |
1703 // TODO(mstensho): Don't add empty fragments. We've always done that in some
cases, but | 1739 // TODO(mstensho): Don't add empty fragments. We've always done that in some |
1704 // there should be no reason to do so. Either filter them out here, or, even
better: pass a | 1740 // cases, but there should be no reason to do so. Either filter them out |
1705 // better clip rectangle to the fragmentainer iterator, so that we won't end
up with empty | 1741 // here, or, even better: pass a better clip rectangle to the fragmentainer |
1706 // fragments here. | 1742 // iterator, so that we won't end up with empty fragments here. |
1707 fragments.append(fragment); | 1743 fragments.append(fragment); |
1708 } | 1744 } |
1709 } | 1745 } |
1710 | 1746 |
1711 static inline LayoutRect frameVisibleRect(LayoutObject* layoutObject) { | 1747 static inline LayoutRect frameVisibleRect(LayoutObject* layoutObject) { |
1712 FrameView* frameView = layoutObject->document().view(); | 1748 FrameView* frameView = layoutObject->document().view(); |
1713 if (!frameView) | 1749 if (!frameView) |
1714 return LayoutRect(); | 1750 return LayoutRect(); |
1715 | 1751 |
1716 return LayoutRect(frameView->visibleContentRect()); | 1752 return LayoutRect(frameView->visibleContentRect()); |
(...skipping 23 matching lines...) Expand all Loading... |
1740 // bounds, then we should fallback to hitting the document. | 1776 // bounds, then we should fallback to hitting the document. |
1741 // For rect-based hit test, we do the fallback only when the hit-rect | 1777 // For rect-based hit test, we do the fallback only when the hit-rect |
1742 // is totally within the document bounds. | 1778 // is totally within the document bounds. |
1743 if (hitTestArea.contains(LayoutRect(hitRect))) { | 1779 if (hitTestArea.contains(LayoutRect(hitRect))) { |
1744 fallback = true; | 1780 fallback = true; |
1745 | 1781 |
1746 // Mouse dragging outside the main document should also be | 1782 // Mouse dragging outside the main document should also be |
1747 // delivered to the document. | 1783 // delivered to the document. |
1748 // TODO(miletus): Capture behavior inconsistent with iframes | 1784 // TODO(miletus): Capture behavior inconsistent with iframes |
1749 // crbug.com/522109. | 1785 // crbug.com/522109. |
1750 // TODO(majidvp): This should apply more consistently across different eve
nt types and we | 1786 // TODO(majidvp): This should apply more consistently across different |
1751 // should not use RequestType for it. Perhaps best for it to be done at a
higher level. See | 1787 // event types and we should not use RequestType for it. Perhaps best for |
1752 // http://crbug.com/505825 | 1788 // it to be done at a higher level. See http://crbug.com/505825 |
1753 } else if ((request.active() || request.release()) && | 1789 } else if ((request.active() || request.release()) && |
1754 !request.isChildFrameHitTest()) { | 1790 !request.isChildFrameHitTest()) { |
1755 fallback = true; | 1791 fallback = true; |
1756 } | 1792 } |
1757 if (fallback) { | 1793 if (fallback) { |
1758 layoutObject()->updateHitTestResult( | 1794 layoutObject()->updateHitTestResult( |
1759 result, toLayoutView(layoutObject()) | 1795 result, toLayoutView(layoutObject()) |
1760 ->flipForWritingMode(hitTestLocation.point())); | 1796 ->flipForWritingMode(hitTestLocation.point())); |
1761 insideLayer = this; | 1797 insideLayer = this; |
1762 | 1798 |
1763 // Don't cache this result since it really wasn't a true hit. | 1799 // Don't cache this result since it really wasn't a true hit. |
1764 result.setCacheable(false); | 1800 result.setCacheable(false); |
1765 } | 1801 } |
1766 } | 1802 } |
1767 | 1803 |
1768 // Now determine if the result is inside an anchor - if the urlElement isn't a
lready set. | 1804 // Now determine if the result is inside an anchor - if the urlElement isn't |
| 1805 // already set. |
1769 Node* node = result.innerNode(); | 1806 Node* node = result.innerNode(); |
1770 if (node && !result.URLElement()) | 1807 if (node && !result.URLElement()) |
1771 result.setURLElement(node->enclosingLinkEventParentOrSelf()); | 1808 result.setURLElement(node->enclosingLinkEventParentOrSelf()); |
1772 | 1809 |
1773 // Now return whether we were inside this layer (this will always be true for
the root | 1810 // Now return whether we were inside this layer (this will always be true for |
1774 // layer). | 1811 // the root layer). |
1775 return insideLayer; | 1812 return insideLayer; |
1776 } | 1813 } |
1777 | 1814 |
1778 Node* PaintLayer::enclosingNode() const { | 1815 Node* PaintLayer::enclosingNode() const { |
1779 for (LayoutObject* r = layoutObject(); r; r = r->parent()) { | 1816 for (LayoutObject* r = layoutObject(); r; r = r->parent()) { |
1780 if (Node* e = r->node()) | 1817 if (Node* e = r->node()) |
1781 return e; | 1818 return e; |
1782 } | 1819 } |
1783 ASSERT_NOT_REACHED(); | 1820 ASSERT_NOT_REACHED(); |
1784 return 0; | 1821 return 0; |
1785 } | 1822 } |
1786 | 1823 |
1787 bool PaintLayer::isInTopLayer() const { | 1824 bool PaintLayer::isInTopLayer() const { |
1788 Node* node = layoutObject()->node(); | 1825 Node* node = layoutObject()->node(); |
1789 return node && node->isElementNode() && toElement(node)->isInTopLayer(); | 1826 return node && node->isElementNode() && toElement(node)->isInTopLayer(); |
1790 } | 1827 } |
1791 | 1828 |
1792 // Compute the z-offset of the point in the transformState. | 1829 // Compute the z-offset of the point in the transformState. |
1793 // This is effectively projecting a ray normal to the plane of ancestor, finding
where that | 1830 // This is effectively projecting a ray normal to the plane of ancestor, finding |
1794 // ray intersects target, and computing the z delta between those two points. | 1831 // where that ray intersects target, and computing the z delta between those two |
| 1832 // points. |
1795 static double computeZOffset(const HitTestingTransformState& transformState) { | 1833 static double computeZOffset(const HitTestingTransformState& transformState) { |
1796 // We got an affine transform, so no z-offset | 1834 // We got an affine transform, so no z-offset |
1797 if (transformState.m_accumulatedTransform.isAffine()) | 1835 if (transformState.m_accumulatedTransform.isAffine()) |
1798 return 0; | 1836 return 0; |
1799 | 1837 |
1800 // Flatten the point into the target plane | 1838 // Flatten the point into the target plane |
1801 FloatPoint targetPoint = transformState.mappedPoint(); | 1839 FloatPoint targetPoint = transformState.mappedPoint(); |
1802 | 1840 |
1803 // Now map the point back through the transform, which computes Z. | 1841 // Now map the point back through the transform, which computes Z. |
1804 FloatPoint3D backmappedPoint = | 1842 FloatPoint3D backmappedPoint = |
1805 transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint)); | 1843 transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint)); |
1806 return backmappedPoint.z(); | 1844 return backmappedPoint.z(); |
1807 } | 1845 } |
1808 | 1846 |
1809 PassRefPtr<HitTestingTransformState> PaintLayer::createLocalTransformState( | 1847 PassRefPtr<HitTestingTransformState> PaintLayer::createLocalTransformState( |
1810 PaintLayer* rootLayer, | 1848 PaintLayer* rootLayer, |
1811 PaintLayer* containerLayer, | 1849 PaintLayer* containerLayer, |
1812 const LayoutRect& hitTestRect, | 1850 const LayoutRect& hitTestRect, |
1813 const HitTestLocation& hitTestLocation, | 1851 const HitTestLocation& hitTestLocation, |
1814 const HitTestingTransformState* containerTransformState, | 1852 const HitTestingTransformState* containerTransformState, |
1815 const LayoutPoint& translationOffset) const { | 1853 const LayoutPoint& translationOffset) const { |
1816 RefPtr<HitTestingTransformState> transformState; | 1854 RefPtr<HitTestingTransformState> transformState; |
1817 LayoutPoint offset; | 1855 LayoutPoint offset; |
1818 if (containerTransformState) { | 1856 if (containerTransformState) { |
1819 // If we're already computing transform state, then it's relative to the con
tainer (which we know is non-null). | 1857 // If we're already computing transform state, then it's relative to the |
| 1858 // container (which we know is non-null). |
1820 transformState = HitTestingTransformState::create(*containerTransformState); | 1859 transformState = HitTestingTransformState::create(*containerTransformState); |
1821 convertToLayerCoords(containerLayer, offset); | 1860 convertToLayerCoords(containerLayer, offset); |
1822 } else { | 1861 } else { |
1823 // If this is the first time we need to make transform state, then base it o
ff of hitTestLocation, | 1862 // If this is the first time we need to make transform state, then base it |
1824 // which is relative to rootLayer. | 1863 // off of hitTestLocation, which is relative to rootLayer. |
1825 transformState = HitTestingTransformState::create( | 1864 transformState = HitTestingTransformState::create( |
1826 hitTestLocation.transformedPoint(), hitTestLocation.transformedRect(), | 1865 hitTestLocation.transformedPoint(), hitTestLocation.transformedRect(), |
1827 FloatQuad(FloatRect(hitTestRect))); | 1866 FloatQuad(FloatRect(hitTestRect))); |
1828 convertToLayerCoords(rootLayer, offset); | 1867 convertToLayerCoords(rootLayer, offset); |
1829 } | 1868 } |
1830 offset.moveBy(translationOffset); | 1869 offset.moveBy(translationOffset); |
1831 | 1870 |
1832 LayoutObject* containerLayoutObject = | 1871 LayoutObject* containerLayoutObject = |
1833 containerLayer ? containerLayer->layoutObject() : 0; | 1872 containerLayer ? containerLayer->layoutObject() : 0; |
1834 if (layoutObject()->shouldUseTransformFromContainer(containerLayoutObject)) { | 1873 if (layoutObject()->shouldUseTransformFromContainer(containerLayoutObject)) { |
(...skipping 10 matching lines...) Expand all Loading... |
1845 return transformState; | 1884 return transformState; |
1846 } | 1885 } |
1847 | 1886 |
1848 static bool isHitCandidate(const PaintLayer* hitLayer, | 1887 static bool isHitCandidate(const PaintLayer* hitLayer, |
1849 bool canDepthSort, | 1888 bool canDepthSort, |
1850 double* zOffset, | 1889 double* zOffset, |
1851 const HitTestingTransformState* transformState) { | 1890 const HitTestingTransformState* transformState) { |
1852 if (!hitLayer) | 1891 if (!hitLayer) |
1853 return false; | 1892 return false; |
1854 | 1893 |
1855 // The hit layer is depth-sorting with other layers, so just say that it was h
it. | 1894 // The hit layer is depth-sorting with other layers, so just say that it was |
| 1895 // hit. |
1856 if (canDepthSort) | 1896 if (canDepthSort) |
1857 return true; | 1897 return true; |
1858 | 1898 |
1859 // We need to look at z-depth to decide if this layer was hit. | 1899 // We need to look at z-depth to decide if this layer was hit. |
1860 if (zOffset) { | 1900 if (zOffset) { |
1861 ASSERT(transformState); | 1901 ASSERT(transformState); |
1862 // This is actually computing our z, but that's OK because the hitLayer is c
oplanar with us. | 1902 // This is actually computing our z, but that's OK because the hitLayer is |
| 1903 // coplanar with us. |
1863 double childZOffset = computeZOffset(*transformState); | 1904 double childZOffset = computeZOffset(*transformState); |
1864 if (childZOffset > *zOffset) { | 1905 if (childZOffset > *zOffset) { |
1865 *zOffset = childZOffset; | 1906 *zOffset = childZOffset; |
1866 return true; | 1907 return true; |
1867 } | 1908 } |
1868 return false; | 1909 return false; |
1869 } | 1910 } |
1870 | 1911 |
1871 return true; | 1912 return true; |
1872 } | 1913 } |
1873 | 1914 |
1874 // hitTestLocation and hitTestRect are relative to rootLayer. | 1915 // hitTestLocation and hitTestRect are relative to rootLayer. |
1875 // A 'flattening' layer is one preserves3D() == false. | 1916 // A 'flattening' layer is one preserves3D() == false. |
1876 // transformState.m_accumulatedTransform holds the transform from the containing
flattening layer. | 1917 // transformState.m_accumulatedTransform holds the transform from the containing |
1877 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the c
ontaining flattening layer. | 1918 // flattening layer. |
1878 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of
the containing flattening layer. | 1919 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the |
| 1920 // containing flattening layer. |
| 1921 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of |
| 1922 // the containing flattening layer. |
1879 // | 1923 // |
1880 // If zOffset is non-null (which indicates that the caller wants z offset inform
ation), | 1924 // If zOffset is non-null (which indicates that the caller wants z offset |
1881 // *zOffset on return is the z offset of the hit point relative to the containi
ng flattening layer. | 1925 // information), *zOffset on return is the z offset of the hit point relative to |
| 1926 // the containing flattening layer. |
1882 PaintLayer* PaintLayer::hitTestLayer( | 1927 PaintLayer* PaintLayer::hitTestLayer( |
1883 PaintLayer* rootLayer, | 1928 PaintLayer* rootLayer, |
1884 PaintLayer* containerLayer, | 1929 PaintLayer* containerLayer, |
1885 HitTestResult& result, | 1930 HitTestResult& result, |
1886 const LayoutRect& hitTestRect, | 1931 const LayoutRect& hitTestRect, |
1887 const HitTestLocation& hitTestLocation, | 1932 const HitTestLocation& hitTestLocation, |
1888 bool appliedTransform, | 1933 bool appliedTransform, |
1889 const HitTestingTransformState* transformState, | 1934 const HitTestingTransformState* transformState, |
1890 double* zOffset) { | 1935 double* zOffset) { |
1891 DCHECK(layoutObject()->document().lifecycle().state() >= | 1936 DCHECK(layoutObject()->document().lifecycle().state() >= |
(...skipping 29 matching lines...) Expand all Loading... |
1921 transformState, zOffset); | 1966 transformState, zOffset); |
1922 } | 1967 } |
1923 | 1968 |
1924 if (hitTestClippedOutByClipPath(rootLayer, hitTestLocation)) | 1969 if (hitTestClippedOutByClipPath(rootLayer, hitTestLocation)) |
1925 return nullptr; | 1970 return nullptr; |
1926 | 1971 |
1927 // Ensure our lists and 3d status are up to date. | 1972 // Ensure our lists and 3d status are up to date. |
1928 m_stackingNode->updateLayerListsIfNeeded(); | 1973 m_stackingNode->updateLayerListsIfNeeded(); |
1929 update3DTransformedDescendantStatus(); | 1974 update3DTransformedDescendantStatus(); |
1930 | 1975 |
1931 // The natural thing would be to keep HitTestingTransformState on the stack, b
ut it's big, so we heap-allocate. | 1976 // The natural thing would be to keep HitTestingTransformState on the stack, |
| 1977 // but it's big, so we heap-allocate. |
1932 RefPtr<HitTestingTransformState> localTransformState; | 1978 RefPtr<HitTestingTransformState> localTransformState; |
1933 if (appliedTransform) { | 1979 if (appliedTransform) { |
1934 // We computed the correct state in the caller (above code), so just referen
ce it. | 1980 // We computed the correct state in the caller (above code), so just |
| 1981 // reference it. |
1935 ASSERT(transformState); | 1982 ASSERT(transformState); |
1936 localTransformState = const_cast<HitTestingTransformState*>(transformState); | 1983 localTransformState = const_cast<HitTestingTransformState*>(transformState); |
1937 } else if (transformState || m_has3DTransformedDescendant || preserves3D()) { | 1984 } else if (transformState || m_has3DTransformedDescendant || preserves3D()) { |
1938 // We need transform state for the first time, or to offset the container st
ate, so create it here. | 1985 // We need transform state for the first time, or to offset the container |
| 1986 // state, so create it here. |
1939 localTransformState = | 1987 localTransformState = |
1940 createLocalTransformState(rootLayer, containerLayer, hitTestRect, | 1988 createLocalTransformState(rootLayer, containerLayer, hitTestRect, |
1941 hitTestLocation, transformState); | 1989 hitTestLocation, transformState); |
1942 } | 1990 } |
1943 | 1991 |
1944 // Check for hit test on backface if backface-visibility is 'hidden' | 1992 // Check for hit test on backface if backface-visibility is 'hidden' |
1945 if (localTransformState && | 1993 if (localTransformState && |
1946 layoutObject()->style()->backfaceVisibility() == | 1994 layoutObject()->style()->backfaceVisibility() == |
1947 BackfaceVisibilityHidden) { | 1995 BackfaceVisibilityHidden) { |
1948 TransformationMatrix invertedMatrix = | 1996 TransformationMatrix invertedMatrix = |
1949 localTransformState->m_accumulatedTransform.inverse(); | 1997 localTransformState->m_accumulatedTransform.inverse(); |
1950 // If the z-vector of the matrix is negative, the back is facing towards the
viewer. | 1998 // If the z-vector of the matrix is negative, the back is facing towards the |
| 1999 // viewer. |
1951 if (invertedMatrix.m33() < 0) | 2000 if (invertedMatrix.m33() < 0) |
1952 return nullptr; | 2001 return nullptr; |
1953 } | 2002 } |
1954 | 2003 |
1955 RefPtr<HitTestingTransformState> unflattenedTransformState = | 2004 RefPtr<HitTestingTransformState> unflattenedTransformState = |
1956 localTransformState; | 2005 localTransformState; |
1957 if (localTransformState && !preserves3D()) { | 2006 if (localTransformState && !preserves3D()) { |
1958 // Keep a copy of the pre-flattening state, for computing z-offsets for the
container | 2007 // Keep a copy of the pre-flattening state, for computing z-offsets for the |
| 2008 // container |
1959 unflattenedTransformState = | 2009 unflattenedTransformState = |
1960 HitTestingTransformState::create(*localTransformState); | 2010 HitTestingTransformState::create(*localTransformState); |
1961 // This layer is flattening, so flatten the state passed to descendants. | 2011 // This layer is flattening, so flatten the state passed to descendants. |
1962 localTransformState->flatten(); | 2012 localTransformState->flatten(); |
1963 } | 2013 } |
1964 | 2014 |
1965 // The following are used for keeping track of the z-depth of the hit point of
3d-transformed | 2015 // The following are used for keeping track of the z-depth of the hit point of |
1966 // descendants. | 2016 // 3d-transformed descendants. |
1967 double localZOffset = -std::numeric_limits<double>::infinity(); | 2017 double localZOffset = -std::numeric_limits<double>::infinity(); |
1968 double* zOffsetForDescendantsPtr = 0; | 2018 double* zOffsetForDescendantsPtr = 0; |
1969 double* zOffsetForContentsPtr = 0; | 2019 double* zOffsetForContentsPtr = 0; |
1970 | 2020 |
1971 bool depthSortDescendants = false; | 2021 bool depthSortDescendants = false; |
1972 if (preserves3D()) { | 2022 if (preserves3D()) { |
1973 depthSortDescendants = true; | 2023 depthSortDescendants = true; |
1974 // Our layers can depth-test with our container, so share the z depth pointe
r with the container, if it passed one down. | 2024 // Our layers can depth-test with our container, so share the z depth |
| 2025 // pointer with the container, if it passed one down. |
1975 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset; | 2026 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset; |
1976 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset; | 2027 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset; |
1977 } else if (zOffset) { | 2028 } else if (zOffset) { |
1978 zOffsetForDescendantsPtr = 0; | 2029 zOffsetForDescendantsPtr = 0; |
1979 // Container needs us to give back a z offset for the hit layer. | 2030 // Container needs us to give back a z offset for the hit layer. |
1980 zOffsetForContentsPtr = zOffset; | 2031 zOffsetForContentsPtr = zOffset; |
1981 } | 2032 } |
1982 | 2033 |
1983 // This variable tracks which layer the mouse ends up being inside. | 2034 // This variable tracks which layer the mouse ends up being inside. |
1984 PaintLayer* candidateLayer = 0; | 2035 PaintLayer* candidateLayer = 0; |
1985 | 2036 |
1986 // Begin by walking our list of positive layers from highest z-index down to t
he lowest z-index. | 2037 // Begin by walking our list of positive layers from highest z-index down to |
| 2038 // the lowest z-index. |
1987 PaintLayer* hitLayer = hitTestChildren( | 2039 PaintLayer* hitLayer = hitTestChildren( |
1988 PositiveZOrderChildren, rootLayer, result, hitTestRect, hitTestLocation, | 2040 PositiveZOrderChildren, rootLayer, result, hitTestRect, hitTestLocation, |
1989 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, | 2041 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, |
1990 unflattenedTransformState.get(), depthSortDescendants); | 2042 unflattenedTransformState.get(), depthSortDescendants); |
1991 if (hitLayer) { | 2043 if (hitLayer) { |
1992 if (!depthSortDescendants) | 2044 if (!depthSortDescendants) |
1993 return hitLayer; | 2045 return hitLayer; |
1994 candidateLayer = hitLayer; | 2046 candidateLayer = hitLayer; |
1995 } | 2047 } |
1996 | 2048 |
1997 // Now check our overflow objects. | 2049 // Now check our overflow objects. |
1998 hitLayer = hitTestChildren( | 2050 hitLayer = hitTestChildren( |
1999 NormalFlowChildren, rootLayer, result, hitTestRect, hitTestLocation, | 2051 NormalFlowChildren, rootLayer, result, hitTestRect, hitTestLocation, |
2000 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, | 2052 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, |
2001 unflattenedTransformState.get(), depthSortDescendants); | 2053 unflattenedTransformState.get(), depthSortDescendants); |
2002 if (hitLayer) { | 2054 if (hitLayer) { |
2003 if (!depthSortDescendants) | 2055 if (!depthSortDescendants) |
2004 return hitLayer; | 2056 return hitLayer; |
2005 candidateLayer = hitLayer; | 2057 candidateLayer = hitLayer; |
2006 } | 2058 } |
2007 | 2059 |
2008 // Collect the fragments. This will compute the clip rectangles for each layer
fragment. | 2060 // Collect the fragments. This will compute the clip rectangles for each layer |
| 2061 // fragment. |
2009 PaintLayerFragments layerFragments; | 2062 PaintLayerFragments layerFragments; |
2010 if (appliedTransform) | 2063 if (appliedTransform) |
2011 appendSingleFragmentIgnoringPagination( | 2064 appendSingleFragmentIgnoringPagination( |
2012 layerFragments, rootLayer, hitTestRect, clipRectsCacheSlot, | 2065 layerFragments, rootLayer, hitTestRect, clipRectsCacheSlot, |
2013 ExcludeOverlayScrollbarSizeForHitTesting); | 2066 ExcludeOverlayScrollbarSizeForHitTesting); |
2014 else | 2067 else |
2015 collectFragments(layerFragments, rootLayer, hitTestRect, clipRectsCacheSlot, | 2068 collectFragments(layerFragments, rootLayer, hitTestRect, clipRectsCacheSlot, |
2016 ExcludeOverlayScrollbarSizeForHitTesting); | 2069 ExcludeOverlayScrollbarSizeForHitTesting); |
2017 | 2070 |
2018 if (m_scrollableArea && | 2071 if (m_scrollableArea && |
2019 m_scrollableArea->hitTestResizerInFragments(layerFragments, | 2072 m_scrollableArea->hitTestResizerInFragments(layerFragments, |
2020 hitTestLocation)) { | 2073 hitTestLocation)) { |
2021 layoutObject()->updateHitTestResult(result, hitTestLocation.point()); | 2074 layoutObject()->updateHitTestResult(result, hitTestLocation.point()); |
2022 return this; | 2075 return this; |
2023 } | 2076 } |
2024 | 2077 |
2025 // Next we want to see if the mouse pos is inside the child LayoutObjects of t
he layer. Check | 2078 // Next we want to see if the mouse pos is inside the child LayoutObjects of |
2026 // every fragment in reverse order. | 2079 // the layer. Check every fragment in reverse order. |
2027 if (isSelfPaintingLayer()) { | 2080 if (isSelfPaintingLayer()) { |
2028 // Hit test with a temporary HitTestResult, because we only want to commit t
o 'result' if we know we're frontmost. | 2081 // Hit test with a temporary HitTestResult, because we only want to commit |
| 2082 // to 'result' if we know we're frontmost. |
2029 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation()); | 2083 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation()); |
2030 bool insideFragmentForegroundRect = false; | 2084 bool insideFragmentForegroundRect = false; |
2031 if (hitTestContentsForFragments(layerFragments, tempResult, hitTestLocation, | 2085 if (hitTestContentsForFragments(layerFragments, tempResult, hitTestLocation, |
2032 HitTestDescendants, | 2086 HitTestDescendants, |
2033 insideFragmentForegroundRect) && | 2087 insideFragmentForegroundRect) && |
2034 isHitCandidate(this, false, zOffsetForContentsPtr, | 2088 isHitCandidate(this, false, zOffsetForContentsPtr, |
2035 unflattenedTransformState.get())) { | 2089 unflattenedTransformState.get())) { |
2036 if (result.hitTestRequest().listBased()) | 2090 if (result.hitTestRequest().listBased()) |
2037 result.append(tempResult); | 2091 result.append(tempResult); |
2038 else | 2092 else |
2039 result = tempResult; | 2093 result = tempResult; |
2040 if (!depthSortDescendants) | 2094 if (!depthSortDescendants) |
2041 return this; | 2095 return this; |
2042 // Foreground can depth-sort with descendant layers, so keep this as a can
didate. | 2096 // Foreground can depth-sort with descendant layers, so keep this as a |
| 2097 // candidate. |
2043 candidateLayer = this; | 2098 candidateLayer = this; |
2044 } else if (insideFragmentForegroundRect && | 2099 } else if (insideFragmentForegroundRect && |
2045 result.hitTestRequest().listBased()) { | 2100 result.hitTestRequest().listBased()) { |
2046 result.append(tempResult); | 2101 result.append(tempResult); |
2047 } | 2102 } |
2048 } | 2103 } |
2049 | 2104 |
2050 // Now check our negative z-index children. | 2105 // Now check our negative z-index children. |
2051 hitLayer = hitTestChildren( | 2106 hitLayer = hitTestChildren( |
2052 NegativeZOrderChildren, rootLayer, result, hitTestRect, hitTestLocation, | 2107 NegativeZOrderChildren, rootLayer, result, hitTestRect, hitTestLocation, |
2053 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, | 2108 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, |
2054 unflattenedTransformState.get(), depthSortDescendants); | 2109 unflattenedTransformState.get(), depthSortDescendants); |
2055 if (hitLayer) { | 2110 if (hitLayer) { |
2056 if (!depthSortDescendants) | 2111 if (!depthSortDescendants) |
2057 return hitLayer; | 2112 return hitLayer; |
2058 candidateLayer = hitLayer; | 2113 candidateLayer = hitLayer; |
2059 } | 2114 } |
2060 | 2115 |
2061 // If we found a layer, return. Child layers, and foreground always render in
front of background. | 2116 // If we found a layer, return. Child layers, and foreground always render in |
| 2117 // front of background. |
2062 if (candidateLayer) | 2118 if (candidateLayer) |
2063 return candidateLayer; | 2119 return candidateLayer; |
2064 | 2120 |
2065 if (isSelfPaintingLayer()) { | 2121 if (isSelfPaintingLayer()) { |
2066 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation()); | 2122 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation()); |
2067 bool insideFragmentBackgroundRect = false; | 2123 bool insideFragmentBackgroundRect = false; |
2068 if (hitTestContentsForFragments(layerFragments, tempResult, hitTestLocation, | 2124 if (hitTestContentsForFragments(layerFragments, tempResult, hitTestLocation, |
2069 HitTestSelf, | 2125 HitTestSelf, |
2070 insideFragmentBackgroundRect) && | 2126 insideFragmentBackgroundRect) && |
2071 isHitCandidate(this, false, zOffsetForContentsPtr, | 2127 isHitCandidate(this, false, zOffsetForContentsPtr, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2124 this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, | 2180 this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, |
2125 PaintLayer::RootOfTransparencyClipBox, LayoutSize()); | 2181 PaintLayer::RootOfTransparencyClipBox, LayoutSize()); |
2126 enclosingPaginationLayer()->collectFragments( | 2182 enclosingPaginationLayer()->collectFragments( |
2127 enclosingPaginationFragments, rootLayer, hitTestRect, clipRectsCacheSlot, | 2183 enclosingPaginationFragments, rootLayer, hitTestRect, clipRectsCacheSlot, |
2128 ExcludeOverlayScrollbarSizeForHitTesting, RespectOverflowClip, | 2184 ExcludeOverlayScrollbarSizeForHitTesting, RespectOverflowClip, |
2129 &offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent); | 2185 &offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent); |
2130 | 2186 |
2131 for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) { | 2187 for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) { |
2132 const PaintLayerFragment& fragment = enclosingPaginationFragments.at(i); | 2188 const PaintLayerFragment& fragment = enclosingPaginationFragments.at(i); |
2133 | 2189 |
2134 // Apply the page/column clip for this fragment, as well as any clips establ
ished by layers in between us and | 2190 // Apply the page/column clip for this fragment, as well as any clips |
2135 // the enclosing pagination layer. | 2191 // established by layers in between us and the enclosing pagination layer. |
2136 LayoutRect clipRect = fragment.backgroundRect.rect(); | 2192 LayoutRect clipRect = fragment.backgroundRect.rect(); |
2137 | 2193 |
2138 // Now compute the clips within a given fragment | 2194 // Now compute the clips within a given fragment |
2139 if (parent() != enclosingPaginationLayer()) { | 2195 if (parent() != enclosingPaginationLayer()) { |
2140 enclosingPaginationLayer()->convertToLayerCoords( | 2196 enclosingPaginationLayer()->convertToLayerCoords( |
2141 rootLayer, offsetOfPaginationLayerFromRoot); | 2197 rootLayer, offsetOfPaginationLayerFromRoot); |
2142 LayoutRect parentClipRect = | 2198 LayoutRect parentClipRect = |
2143 clipper() | 2199 clipper() |
2144 .backgroundClipRect(ClipRectsContext( | 2200 .backgroundClipRect(ClipRectsContext( |
2145 enclosingPaginationLayer(), clipRectsCacheSlot, | 2201 enclosingPaginationLayer(), clipRectsCacheSlot, |
(...skipping 29 matching lines...) Expand all Loading... |
2175 // Create a transform state to accumulate this transform. | 2231 // Create a transform state to accumulate this transform. |
2176 RefPtr<HitTestingTransformState> newTransformState = | 2232 RefPtr<HitTestingTransformState> newTransformState = |
2177 createLocalTransformState(rootLayer, containerLayer, hitTestRect, | 2233 createLocalTransformState(rootLayer, containerLayer, hitTestRect, |
2178 hitTestLocation, transformState, | 2234 hitTestLocation, transformState, |
2179 translationOffset); | 2235 translationOffset); |
2180 | 2236 |
2181 // If the transform can't be inverted, then don't hit test this layer at all. | 2237 // If the transform can't be inverted, then don't hit test this layer at all. |
2182 if (!newTransformState->m_accumulatedTransform.isInvertible()) | 2238 if (!newTransformState->m_accumulatedTransform.isInvertible()) |
2183 return 0; | 2239 return 0; |
2184 | 2240 |
2185 // Compute the point and the hit test rect in the coords of this layer by usin
g the values | 2241 // Compute the point and the hit test rect in the coords of this layer by |
2186 // from the transformState, which store the point and quad in the coords of th
e last flattened | 2242 // using the values from the transformState, which store the point and quad in |
2187 // layer, and the accumulated transform which lets up map through preserve-3d
layers. | 2243 // the coords of the last flattened layer, and the accumulated transform which |
| 2244 // lets up map through preserve-3d layers. |
2188 // | 2245 // |
2189 // We can't just map hitTestLocation and hitTestRect because they may have bee
n flattened (losing z) | 2246 // We can't just map hitTestLocation and hitTestRect because they may have |
2190 // by our container. | 2247 // been flattened (losing z) by our container. |
2191 FloatPoint localPoint = newTransformState->mappedPoint(); | 2248 FloatPoint localPoint = newTransformState->mappedPoint(); |
2192 FloatQuad localPointQuad = newTransformState->mappedQuad(); | 2249 FloatQuad localPointQuad = newTransformState->mappedQuad(); |
2193 LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea(); | 2250 LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea(); |
2194 HitTestLocation newHitTestLocation; | 2251 HitTestLocation newHitTestLocation; |
2195 if (hitTestLocation.isRectBasedTest()) | 2252 if (hitTestLocation.isRectBasedTest()) |
2196 newHitTestLocation = HitTestLocation(localPoint, localPointQuad); | 2253 newHitTestLocation = HitTestLocation(localPoint, localPointQuad); |
2197 else | 2254 else |
2198 newHitTestLocation = HitTestLocation(localPoint); | 2255 newHitTestLocation = HitTestLocation(localPoint); |
2199 | 2256 |
2200 // Now do a hit test with the root layer shifted to be us. | 2257 // Now do a hit test with the root layer shifted to be us. |
2201 return hitTestLayer(this, containerLayer, result, localHitTestRect, | 2258 return hitTestLayer(this, containerLayer, result, localHitTestRect, |
2202 newHitTestLocation, true, newTransformState.get(), | 2259 newHitTestLocation, true, newTransformState.get(), |
2203 zOffset); | 2260 zOffset); |
2204 } | 2261 } |
2205 | 2262 |
2206 bool PaintLayer::hitTestContents(HitTestResult& result, | 2263 bool PaintLayer::hitTestContents(HitTestResult& result, |
2207 const LayoutRect& layerBounds, | 2264 const LayoutRect& layerBounds, |
2208 const HitTestLocation& hitTestLocation, | 2265 const HitTestLocation& hitTestLocation, |
2209 HitTestFilter hitTestFilter) const { | 2266 HitTestFilter hitTestFilter) const { |
2210 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); | 2267 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); |
2211 | 2268 |
2212 if (!layoutObject()->hitTest( | 2269 if (!layoutObject()->hitTest( |
2213 result, hitTestLocation, | 2270 result, hitTestLocation, |
2214 toLayoutPoint(layerBounds.location() - layoutBoxLocation()), | 2271 toLayoutPoint(layerBounds.location() - layoutBoxLocation()), |
2215 hitTestFilter)) { | 2272 hitTestFilter)) { |
2216 // It's wrong to set innerNode, but then claim that you didn't hit anything,
unless it is | 2273 // It's wrong to set innerNode, but then claim that you didn't hit anything, |
2217 // a rect-based test. | 2274 // unless it is a rect-based test. |
2218 ASSERT(!result.innerNode() || (result.hitTestRequest().listBased() && | 2275 ASSERT(!result.innerNode() || (result.hitTestRequest().listBased() && |
2219 result.listBasedTestResult().size())); | 2276 result.listBasedTestResult().size())); |
2220 return false; | 2277 return false; |
2221 } | 2278 } |
2222 | 2279 |
2223 if (!result.innerNode()) { | 2280 if (!result.innerNode()) { |
2224 // We hit something anonymous, and we didn't find a DOM node ancestor in thi
s layer. | 2281 // We hit something anonymous, and we didn't find a DOM node ancestor in |
| 2282 // this layer. |
2225 | 2283 |
2226 if (layoutObject()->isLayoutFlowThread()) { | 2284 if (layoutObject()->isLayoutFlowThread()) { |
2227 // For a flow thread it's safe to just say that we didn't hit anything. Th
at means that | 2285 // For a flow thread it's safe to just say that we didn't hit anything. |
2228 // we'll continue as normally, and eventually hit a column set sibling ins
tead. Column | 2286 // That means that we'll continue as normally, and eventually hit a column |
2229 // sets are also anonymous, but, unlike flow threads, they don't establish
layers, so | 2287 // set sibling instead. Column sets are also anonymous, but, unlike flow |
2230 // we'll fall back and hit the multicol container parent (which should hav
e a DOM node). | 2288 // threads, they don't establish layers, so we'll fall back and hit the |
| 2289 // multicol container parent (which should have a DOM node). |
2231 return false; | 2290 return false; |
2232 } | 2291 } |
2233 | 2292 |
2234 Node* e = enclosingNode(); | 2293 Node* e = enclosingNode(); |
2235 // FIXME: should be a call to result.setNodeAndPosition. What we would reall
y want to do here is to | 2294 // FIXME: should be a call to result.setNodeAndPosition. What we would |
2236 // return and look for the nearest non-anonymous ancestor, and ignore aunts
and uncles on | 2295 // really want to do here is to return and look for the nearest |
2237 // our way. It's bad to look for it manually like we do here, and give up on
setting a local | 2296 // non-anonymous ancestor, and ignore aunts and uncles on our way. It's bad |
2238 // point in the result, because that has bad implications for text selection
and | 2297 // to look for it manually like we do here, and give up on setting a local |
2239 // caretRangeFromPoint(). See crbug.com/461791 | 2298 // point in the result, because that has bad implications for text selection |
| 2299 // and caretRangeFromPoint(). See crbug.com/461791 |
2240 if (!result.innerNode()) | 2300 if (!result.innerNode()) |
2241 result.setInnerNode(e); | 2301 result.setInnerNode(e); |
2242 } | 2302 } |
2243 return true; | 2303 return true; |
2244 } | 2304 } |
2245 | 2305 |
2246 PaintLayer* PaintLayer::hitTestChildren( | 2306 PaintLayer* PaintLayer::hitTestChildren( |
2247 ChildrenIteration childrentoVisit, | 2307 ChildrenIteration childrentoVisit, |
2248 PaintLayer* rootLayer, | 2308 PaintLayer* rootLayer, |
2249 HitTestResult& result, | 2309 HitTestResult& result, |
(...skipping 11 matching lines...) Expand all Loading... |
2261 PaintLayerStackingNodeReverseIterator iterator(*m_stackingNode, | 2321 PaintLayerStackingNodeReverseIterator iterator(*m_stackingNode, |
2262 childrentoVisit); | 2322 childrentoVisit); |
2263 while (PaintLayerStackingNode* child = iterator.next()) { | 2323 while (PaintLayerStackingNode* child = iterator.next()) { |
2264 PaintLayer* childLayer = child->layer(); | 2324 PaintLayer* childLayer = child->layer(); |
2265 PaintLayer* hitLayer = 0; | 2325 PaintLayer* hitLayer = 0; |
2266 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation()); | 2326 HitTestResult tempResult(result.hitTestRequest(), result.hitTestLocation()); |
2267 hitLayer = childLayer->hitTestLayer(rootLayer, this, tempResult, | 2327 hitLayer = childLayer->hitTestLayer(rootLayer, this, tempResult, |
2268 hitTestRect, hitTestLocation, false, | 2328 hitTestRect, hitTestLocation, false, |
2269 transformState, zOffsetForDescendants); | 2329 transformState, zOffsetForDescendants); |
2270 | 2330 |
2271 // If it is a list-based test, we can safely append the temporary result sin
ce it might had hit | 2331 // If it is a list-based test, we can safely append the temporary result |
2272 // nodes but not necesserily had hitLayer set. | 2332 // since it might had hit nodes but not necesserily had hitLayer set. |
2273 ASSERT(!result.isRectBasedTest() || result.hitTestRequest().listBased()); | 2333 ASSERT(!result.isRectBasedTest() || result.hitTestRequest().listBased()); |
2274 if (result.hitTestRequest().listBased()) | 2334 if (result.hitTestRequest().listBased()) |
2275 result.append(tempResult); | 2335 result.append(tempResult); |
2276 | 2336 |
2277 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, | 2337 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, |
2278 unflattenedTransformState)) { | 2338 unflattenedTransformState)) { |
2279 resultLayer = hitLayer; | 2339 resultLayer = hitLayer; |
2280 if (!result.hitTestRequest().listBased()) | 2340 if (!result.hitTestRequest().listBased()) |
2281 result = tempResult; | 2341 result = tempResult; |
2282 if (!depthSortDescendants) | 2342 if (!depthSortDescendants) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2345 // the point accordingly. | 2405 // the point accordingly. |
2346 if (clipper->clipPathUnits() == SVGUnitTypes::kSvgUnitTypeUserspaceonuse) | 2406 if (clipper->clipPathUnits() == SVGUnitTypes::kSvgUnitTypeUserspaceonuse) |
2347 point.moveBy(-referenceBox.location()); | 2407 point.moveBy(-referenceBox.location()); |
2348 return !clipper->hitTestClipContent(FloatRect(referenceBox), point); | 2408 return !clipper->hitTestClipContent(FloatRect(referenceBox), point); |
2349 } | 2409 } |
2350 | 2410 |
2351 bool PaintLayer::intersectsDamageRect(const LayoutRect& layerBounds, | 2411 bool PaintLayer::intersectsDamageRect(const LayoutRect& layerBounds, |
2352 const LayoutRect& damageRect, | 2412 const LayoutRect& damageRect, |
2353 const LayoutPoint& offsetFromRoot) const { | 2413 const LayoutPoint& offsetFromRoot) const { |
2354 // Always examine the canvas and the root. | 2414 // Always examine the canvas and the root. |
2355 // FIXME: Could eliminate the isDocumentElement() check if we fix background p
ainting so that the LayoutView | 2415 // FIXME: Could eliminate the isDocumentElement() check if we fix background |
2356 // paints the root's background. | 2416 // painting so that the LayoutView paints the root's background. |
2357 if (isRootLayer() || layoutObject()->isDocumentElement()) | 2417 if (isRootLayer() || layoutObject()->isDocumentElement()) |
2358 return true; | 2418 return true; |
2359 | 2419 |
2360 // If we aren't an inline flow, and our layer bounds do intersect the damage r
ect, then we | 2420 // If we aren't an inline flow, and our layer bounds do intersect the damage |
2361 // can go ahead and return true. | 2421 // rect, then we can go ahead and return true. |
2362 LayoutView* view = layoutObject()->view(); | 2422 LayoutView* view = layoutObject()->view(); |
2363 ASSERT(view); | 2423 ASSERT(view); |
2364 if (view && !layoutObject()->isLayoutInline()) { | 2424 if (view && !layoutObject()->isLayoutInline()) { |
2365 if (layerBounds.intersects(damageRect)) | 2425 if (layerBounds.intersects(damageRect)) |
2366 return true; | 2426 return true; |
2367 } | 2427 } |
2368 | 2428 |
2369 // Otherwise we need to compute the bounding box of this single layer and see
if it intersects | 2429 // Otherwise we need to compute the bounding box of this single layer and see |
2370 // the damage rect. | 2430 // if it intersects the damage rect. |
2371 return physicalBoundingBox(offsetFromRoot).intersects(damageRect); | 2431 return physicalBoundingBox(offsetFromRoot).intersects(damageRect); |
2372 } | 2432 } |
2373 | 2433 |
2374 LayoutRect PaintLayer::logicalBoundingBox() const { | 2434 LayoutRect PaintLayer::logicalBoundingBox() const { |
2375 return layoutObject()->visualOverflowRect(); | 2435 return layoutObject()->visualOverflowRect(); |
2376 } | 2436 } |
2377 | 2437 |
2378 static inline LayoutRect flippedLogicalBoundingBox( | 2438 static inline LayoutRect flippedLogicalBoundingBox( |
2379 LayoutRect boundingBox, | 2439 LayoutRect boundingBox, |
2380 LayoutObject* layoutObjects) { | 2440 LayoutObject* layoutObjects) { |
(...skipping 25 matching lines...) Expand all Loading... |
2406 if (!enclosingPaginationLayer()) | 2466 if (!enclosingPaginationLayer()) |
2407 return physicalBoundingBox(ancestorLayer); | 2467 return physicalBoundingBox(ancestorLayer); |
2408 | 2468 |
2409 LayoutRect result = | 2469 LayoutRect result = |
2410 flippedLogicalBoundingBox(logicalBoundingBox(), layoutObject()); | 2470 flippedLogicalBoundingBox(logicalBoundingBox(), layoutObject()); |
2411 convertFromFlowThreadToVisualBoundingBoxInAncestor(ancestorLayer, result); | 2471 convertFromFlowThreadToVisualBoundingBoxInAncestor(ancestorLayer, result); |
2412 return result; | 2472 return result; |
2413 } | 2473 } |
2414 | 2474 |
2415 LayoutRect PaintLayer::boundingBoxForCompositingOverlapTest() const { | 2475 LayoutRect PaintLayer::boundingBoxForCompositingOverlapTest() const { |
2416 // Apply NeverIncludeTransformForAncestorLayer, because the geometry map in Co
mpositingInputsUpdater will take care of applying the | 2476 // Apply NeverIncludeTransformForAncestorLayer, because the geometry map in |
2417 // transform of |this| (== the ancestorLayer argument to boundingBoxForComposi
ting). | 2477 // CompositingInputsUpdater will take care of applying the transform of |this| |
2418 // TODO(trchen): Layer fragmentation is inhibited across compositing boundary.
Should we | 2478 // (== the ancestorLayer argument to boundingBoxForCompositing). |
2419 // return the unfragmented bounds for overlap testing? Or perhaps assume fragm
ented layers | 2479 // TODO(trchen): Layer fragmentation is inhibited across compositing boundary. |
2420 // always overlap? | 2480 // Should we return the unfragmented bounds for overlap testing? Or perhaps |
| 2481 // assume fragmented layers always overlap? |
2421 return overlapBoundsIncludeChildren() | 2482 return overlapBoundsIncludeChildren() |
2422 ? boundingBoxForCompositing(this, | 2483 ? boundingBoxForCompositing(this, |
2423 NeverIncludeTransformForAncestorLayer) | 2484 NeverIncludeTransformForAncestorLayer) |
2424 : fragmentsBoundingBox(this); | 2485 : fragmentsBoundingBox(this); |
2425 } | 2486 } |
2426 | 2487 |
2427 bool PaintLayer::overlapBoundsIncludeChildren() const { | 2488 bool PaintLayer::overlapBoundsIncludeChildren() const { |
2428 return hasFilterThatMovesPixels(); | 2489 return hasFilterThatMovesPixels(); |
2429 } | 2490 } |
2430 | 2491 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2472 | 2533 |
2473 LayoutRect PaintLayer::boundingBoxForCompositing( | 2534 LayoutRect PaintLayer::boundingBoxForCompositing( |
2474 const PaintLayer* ancestorLayer, | 2535 const PaintLayer* ancestorLayer, |
2475 CalculateBoundsOptions options) const { | 2536 CalculateBoundsOptions options) const { |
2476 if (!isSelfPaintingLayer()) | 2537 if (!isSelfPaintingLayer()) |
2477 return LayoutRect(); | 2538 return LayoutRect(); |
2478 | 2539 |
2479 if (!ancestorLayer) | 2540 if (!ancestorLayer) |
2480 ancestorLayer = this; | 2541 ancestorLayer = this; |
2481 | 2542 |
2482 // FIXME: This could be improved to do a check like hasVisibleNonCompositingDe
scendantLayers() (bug 92580). | 2543 // FIXME: This could be improved to do a check like |
| 2544 // hasVisibleNonCompositingDescendantLayers() (bug 92580). |
2483 if (this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant()) | 2545 if (this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant()) |
2484 return LayoutRect(); | 2546 return LayoutRect(); |
2485 | 2547 |
2486 // Without composited scrolling, the root layer is the size of the document. | 2548 // Without composited scrolling, the root layer is the size of the document. |
2487 if (isRootLayer() && !needsCompositedScrolling()) | 2549 if (isRootLayer() && !needsCompositedScrolling()) |
2488 return LayoutRect(m_layoutObject->view()->documentRect()); | 2550 return LayoutRect(m_layoutObject->view()->documentRect()); |
2489 | 2551 |
2490 // The layer created for the LayoutFlowThread is just a helper for painting an
d hit-testing, | 2552 // The layer created for the LayoutFlowThread is just a helper for painting |
2491 // and should not contribute to the bounding box. The LayoutMultiColumnSets wi
ll contribute | 2553 // and hit-testing, and should not contribute to the bounding box. The |
2492 // the correct size for the layout content of the multicol container. | 2554 // LayoutMultiColumnSets will contribute the correct size for the layout |
| 2555 // content of the multicol container. |
2493 if (layoutObject()->isLayoutFlowThread()) | 2556 if (layoutObject()->isLayoutFlowThread()) |
2494 return LayoutRect(); | 2557 return LayoutRect(); |
2495 | 2558 |
2496 // If there is a clip applied by an ancestor to this PaintLayer but below or e
qual to |ancestorLayer|, | 2559 // If there is a clip applied by an ancestor to this PaintLayer but below or |
2497 // use that clip as the bounds rather than the recursive bounding boxes, since
the latter may be larger than the | 2560 // equal to |ancestorLayer|, use that clip as the bounds rather than the |
2498 // actual size. See https://bugs.webkit.org/show_bug.cgi?id=80372 for examples
. | 2561 // recursive bounding boxes, since the latter may be larger than the actual |
| 2562 // size. See https://bugs.webkit.org/show_bug.cgi?id=80372 for examples. |
2499 LayoutRect result = clipper().localClipRect(ancestorLayer); | 2563 LayoutRect result = clipper().localClipRect(ancestorLayer); |
2500 // TODO(chrishtr): avoid converting to IntRect and back. | 2564 // TODO(chrishtr): avoid converting to IntRect and back. |
2501 if (result == LayoutRect(LayoutRect::infiniteIntRect())) { | 2565 if (result == LayoutRect(LayoutRect::infiniteIntRect())) { |
2502 result = physicalBoundingBox(LayoutPoint()); | 2566 result = physicalBoundingBox(LayoutPoint()); |
2503 | 2567 |
2504 const_cast<PaintLayer*>(this)->stackingNode()->updateLayerListsIfNeeded(); | 2568 const_cast<PaintLayer*>(this)->stackingNode()->updateLayerListsIfNeeded(); |
2505 | 2569 |
2506 expandRectForStackingChildren(this, result, options); | 2570 expandRectForStackingChildren(this, result, options); |
2507 | 2571 |
2508 // Only enlarge by the filter outsets if we know the filter is going to be r
endered in software. | 2572 // Only enlarge by the filter outsets if we know the filter is going to be |
2509 // Accelerated filters will handle their own outsets. | 2573 // rendered in software. Accelerated filters will handle their own outsets. |
2510 if (paintsWithFilters()) | 2574 if (paintsWithFilters()) |
2511 result = mapLayoutRectForFilter(result); | 2575 result = mapLayoutRectForFilter(result); |
2512 } | 2576 } |
2513 | 2577 |
2514 if (transform() && (options == IncludeTransformsAndCompositedChildLayers || | 2578 if (transform() && (options == IncludeTransformsAndCompositedChildLayers || |
2515 ((paintsWithTransform(GlobalPaintNormalPhase) && | 2579 ((paintsWithTransform(GlobalPaintNormalPhase) && |
2516 (this != ancestorLayer || | 2580 (this != ancestorLayer || |
2517 options == MaybeIncludeTransformForAncestorLayer))))) | 2581 options == MaybeIncludeTransformForAncestorLayer))))) |
2518 result = transform()->mapRect(result); | 2582 result = transform()->mapRect(result); |
2519 | 2583 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2599 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate( | 2663 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate( |
2600 GraphicsLayerUpdateSubtree); | 2664 GraphicsLayerUpdateSubtree); |
2601 | 2665 |
2602 updateOrRemoveFilterEffect(); | 2666 updateOrRemoveFilterEffect(); |
2603 } | 2667 } |
2604 | 2668 |
2605 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) { | 2669 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) { |
2606 if (!layerBeingDestroyed) { | 2670 if (!layerBeingDestroyed) { |
2607 // We need to make sure our decendants get a geometry update. In principle, | 2671 // We need to make sure our decendants get a geometry update. In principle, |
2608 // we could call setNeedsGraphicsLayerUpdate on our children, but that would | 2672 // we could call setNeedsGraphicsLayerUpdate on our children, but that would |
2609 // require walking the z-order lists to find them. Instead, we over-invalida
te | 2673 // require walking the z-order lists to find them. Instead, we |
2610 // by marking our parent as needing a geometry update. | 2674 // over-invalidate by marking our parent as needing a geometry update. |
2611 if (PaintLayer* compositingParent = | 2675 if (PaintLayer* compositingParent = |
2612 enclosingLayerWithCompositedLayerMapping(ExcludeSelf)) | 2676 enclosingLayerWithCompositedLayerMapping(ExcludeSelf)) |
2613 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate( | 2677 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate( |
2614 GraphicsLayerUpdateSubtree); | 2678 GraphicsLayerUpdateSubtree); |
2615 } | 2679 } |
2616 | 2680 |
2617 if (m_rareData) | 2681 if (m_rareData) |
2618 m_rareData->compositedLayerMapping.reset(); | 2682 m_rareData->compositedLayerMapping.reset(); |
2619 | 2683 |
2620 if (!layerBeingDestroyed) | 2684 if (!layerBeingDestroyed) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2653 layoutObject()->style()->position() == FixedPosition) && | 2717 layoutObject()->style()->position() == FixedPosition) && |
2654 ((globalPaintFlags & GlobalPaintFlattenCompositingLayers) || | 2718 ((globalPaintFlags & GlobalPaintFlattenCompositingLayers) || |
2655 compositingState() != PaintsIntoOwnBacking); | 2719 compositingState() != PaintsIntoOwnBacking); |
2656 } | 2720 } |
2657 | 2721 |
2658 bool PaintLayer::backgroundIsKnownToBeOpaqueInRect( | 2722 bool PaintLayer::backgroundIsKnownToBeOpaqueInRect( |
2659 const LayoutRect& localRect) const { | 2723 const LayoutRect& localRect) const { |
2660 if (paintsWithTransparency(GlobalPaintNormalPhase)) | 2724 if (paintsWithTransparency(GlobalPaintNormalPhase)) |
2661 return false; | 2725 return false; |
2662 | 2726 |
2663 // We can't use hasVisibleContent(), because that will be true if our layoutOb
ject is hidden, but some child | 2727 // We can't use hasVisibleContent(), because that will be true if our |
2664 // is visible and that child doesn't cover the entire rect. | 2728 // layoutObject is hidden, but some child is visible and that child doesn't |
| 2729 // cover the entire rect. |
2665 if (layoutObject()->style()->visibility() != EVisibility::Visible) | 2730 if (layoutObject()->style()->visibility() != EVisibility::Visible) |
2666 return false; | 2731 return false; |
2667 | 2732 |
2668 if (paintsWithFilters() && | 2733 if (paintsWithFilters() && |
2669 layoutObject()->style()->filter().hasFilterThatAffectsOpacity()) | 2734 layoutObject()->style()->filter().hasFilterThatAffectsOpacity()) |
2670 return false; | 2735 return false; |
2671 | 2736 |
2672 // FIXME: Handle simple transforms. | 2737 // FIXME: Handle simple transforms. |
2673 if (transform() && compositingState() != PaintsIntoOwnBacking) | 2738 if (transform() && compositingState() != PaintsIntoOwnBacking) |
2674 return false; | 2739 return false; |
2675 | 2740 |
2676 if (!RuntimeEnabledFeatures::compositeOpaqueFixedPositionEnabled() && | 2741 if (!RuntimeEnabledFeatures::compositeOpaqueFixedPositionEnabled() && |
2677 layoutObject()->style()->position() == FixedPosition && | 2742 layoutObject()->style()->position() == FixedPosition && |
2678 compositingState() != PaintsIntoOwnBacking) | 2743 compositingState() != PaintsIntoOwnBacking) |
2679 return false; | 2744 return false; |
2680 | 2745 |
2681 // This function should not be called when layer-lists are dirty. | 2746 // This function should not be called when layer-lists are dirty. |
2682 // TODO(schenney) This check never hits in layout tests or most platforms, but
does hit in | 2747 // TODO(schenney) This check never hits in layout tests or most platforms, but |
2683 // PopupBlockerBrowserTest.AllowPopupThroughContentSetting on Win 7 Test Build
er. | 2748 // does hit in PopupBlockerBrowserTest.AllowPopupThroughContentSetting on |
| 2749 // Win 7 Test Builder. |
2684 if (m_stackingNode->zOrderListsDirty()) | 2750 if (m_stackingNode->zOrderListsDirty()) |
2685 return false; | 2751 return false; |
2686 | 2752 |
2687 // FIXME: We currently only check the immediate layoutObject, | 2753 // FIXME: We currently only check the immediate layoutObject, |
2688 // which will miss many cases where additional layout objects paint | 2754 // which will miss many cases where additional layout objects paint |
2689 // into this layer. | 2755 // into this layer. |
2690 if (layoutObject()->backgroundIsKnownToBeOpaqueInRect(localRect)) | 2756 if (layoutObject()->backgroundIsKnownToBeOpaqueInRect(localRect)) |
2691 return true; | 2757 return true; |
2692 | 2758 |
2693 // We can't consult child layers if we clip, since they might cover | 2759 // We can't consult child layers if we clip, since they might cover |
2694 // parts of the rect that are clipped out. | 2760 // parts of the rect that are clipped out. |
2695 if (layoutObject()->hasClipRelatedProperty()) | 2761 if (layoutObject()->hasClipRelatedProperty()) |
2696 return false; | 2762 return false; |
2697 | 2763 |
2698 // TODO(schenney): This could be improved by unioning the opaque regions of al
l the children. | 2764 // TODO(schenney): This could be improved by unioning the opaque regions of |
2699 // That would require a refactoring because currently children just check they
at least | 2765 // all the children. That would require a refactoring because currently |
2700 // cover the given rect, but a unioning method would require children to compu
te and report | 2766 // children just check they at least cover the given rect, but a unioning |
2701 // their rects. | 2767 // method would require children to compute and report their rects. |
2702 return childBackgroundIsKnownToBeOpaqueInRect(localRect); | 2768 return childBackgroundIsKnownToBeOpaqueInRect(localRect); |
2703 } | 2769 } |
2704 | 2770 |
2705 bool PaintLayer::childBackgroundIsKnownToBeOpaqueInRect( | 2771 bool PaintLayer::childBackgroundIsKnownToBeOpaqueInRect( |
2706 const LayoutRect& localRect) const { | 2772 const LayoutRect& localRect) const { |
2707 PaintLayerStackingNodeReverseIterator reverseIterator( | 2773 PaintLayerStackingNodeReverseIterator reverseIterator( |
2708 *m_stackingNode, | 2774 *m_stackingNode, |
2709 PositiveZOrderChildren | NormalFlowChildren | NegativeZOrderChildren); | 2775 PositiveZOrderChildren | NormalFlowChildren | NegativeZOrderChildren); |
2710 while (PaintLayerStackingNode* child = reverseIterator.next()) { | 2776 while (PaintLayerStackingNode* child = reverseIterator.next()) { |
2711 const PaintLayer* childLayer = child->layer(); | 2777 const PaintLayer* childLayer = child->layer(); |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3058 return; | 3124 return; |
3059 } | 3125 } |
3060 | 3126 |
3061 ensureFilterInfo().setLastEffect(nullptr); | 3127 ensureFilterInfo().setLastEffect(nullptr); |
3062 } | 3128 } |
3063 | 3129 |
3064 void PaintLayer::filterNeedsPaintInvalidation() { | 3130 void PaintLayer::filterNeedsPaintInvalidation() { |
3065 { | 3131 { |
3066 DeprecatedScheduleStyleRecalcDuringLayout marker( | 3132 DeprecatedScheduleStyleRecalcDuringLayout marker( |
3067 layoutObject()->document().lifecycle()); | 3133 layoutObject()->document().lifecycle()); |
3068 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style re
calc, which | 3134 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style |
3069 // is a problem because this function can be called right before performing
layout but | 3135 // recalc, which is a problem because this function can be called right |
3070 // after style recalc. | 3136 // before performing layout but after style recalc. |
3071 // | 3137 // |
3072 // See LayoutView::layout() and the call to | 3138 // See LayoutView::layout() and the call to |
3073 // invalidateSVGRootsWithRelativeLengthDescendents(). This violation is work
ed around | 3139 // invalidateSVGRootsWithRelativeLengthDescendents(). This violation is |
3074 // in FrameView::updateStyleAndLayoutIfNeededRecursive() by doing an extra s
tyle recalc | 3140 // worked around in FrameView::updateStyleAndLayoutIfNeededRecursive() by |
3075 // and layout in case it's needed. | 3141 // doing an extra style recalc and layout in case it's needed. |
3076 toElement(layoutObject()->node())->scheduleSVGFilterLayerUpdateHack(); | 3142 toElement(layoutObject()->node())->scheduleSVGFilterLayerUpdateHack(); |
3077 } | 3143 } |
3078 | 3144 |
3079 layoutObject()->setShouldDoFullPaintInvalidation(); | 3145 layoutObject()->setShouldDoFullPaintInvalidation(); |
3080 } | 3146 } |
3081 | 3147 |
3082 void PaintLayer::addLayerHitTestRects(LayerHitTestRects& rects) const { | 3148 void PaintLayer::addLayerHitTestRects(LayerHitTestRects& rects) const { |
3083 computeSelfHitTestRects(rects); | 3149 computeSelfHitTestRects(rects); |
3084 for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) | 3150 for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) |
3085 child->addLayerHitTestRects(rects); | 3151 child->addLayerHitTestRects(rects); |
3086 } | 3152 } |
3087 | 3153 |
3088 void PaintLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const { | 3154 void PaintLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const { |
3089 if (!size().isEmpty()) { | 3155 if (!size().isEmpty()) { |
3090 Vector<LayoutRect> rect; | 3156 Vector<LayoutRect> rect; |
3091 | 3157 |
3092 if (layoutBox() && layoutBox()->scrollsOverflow()) { | 3158 if (layoutBox() && layoutBox()->scrollsOverflow()) { |
3093 // For scrolling layers, rects are taken to be in the space of the content
s. | 3159 // For scrolling layers, rects are taken to be in the space of the |
3094 // We need to include the bounding box of the layer in the space of its pa
rent | 3160 // contents. We need to include the bounding box of the layer in the |
3095 // (eg. for border / scroll bars) and if it's composited then the entire c
ontents | 3161 // space of its parent (eg. for border / scroll bars) and if it's |
3096 // as well as they may be on another composited layer. Skip reporting cont
ents | 3162 // composited then the entire contents as well as they may be on another |
3097 // for non-composited layers as they'll get projected to the same layer as
the | 3163 // composited layer. Skip reporting contents for non-composited layers as |
3098 // bounding box. | 3164 // they'll get projected to the same layer as the bounding box. |
3099 if (compositingState() != NotComposited) | 3165 if (compositingState() != NotComposited) |
3100 rect.append(m_scrollableArea->overflowRect()); | 3166 rect.append(m_scrollableArea->overflowRect()); |
3101 | 3167 |
3102 rects.set(this, rect); | 3168 rects.set(this, rect); |
3103 if (const PaintLayer* parentLayer = parent()) { | 3169 if (const PaintLayer* parentLayer = parent()) { |
3104 LayerHitTestRects::iterator iter = rects.find(parentLayer); | 3170 LayerHitTestRects::iterator iter = rects.find(parentLayer); |
3105 if (iter == rects.end()) { | 3171 if (iter == rects.end()) { |
3106 rects.add(parentLayer, Vector<LayoutRect>()) | 3172 rects.add(parentLayer, Vector<LayoutRect>()) |
3107 .storedValue->value.append(physicalBoundingBox(parentLayer)); | 3173 .storedValue->value.append(physicalBoundingBox(parentLayer)); |
3108 } else { | 3174 } else { |
3109 iter->value.append(physicalBoundingBox(parentLayer)); | 3175 iter->value.append(physicalBoundingBox(parentLayer)); |
3110 } | 3176 } |
3111 } | 3177 } |
3112 } else { | 3178 } else { |
3113 rect.append(logicalBoundingBox()); | 3179 rect.append(logicalBoundingBox()); |
3114 rects.set(this, rect); | 3180 rects.set(this, rect); |
3115 } | 3181 } |
3116 } | 3182 } |
3117 } | 3183 } |
3118 | 3184 |
3119 void PaintLayer::setNeedsRepaint() { | 3185 void PaintLayer::setNeedsRepaint() { |
3120 setNeedsRepaintInternal(); | 3186 setNeedsRepaintInternal(); |
3121 | 3187 |
3122 // Do this unconditionally to ensure container chain is marked when compositin
g status of the layer changes. | 3188 // Do this unconditionally to ensure container chain is marked when |
| 3189 // compositing status of the layer changes. |
3123 markCompositingContainerChainForNeedsRepaint(); | 3190 markCompositingContainerChainForNeedsRepaint(); |
3124 } | 3191 } |
3125 | 3192 |
3126 void PaintLayer::setNeedsRepaintInternal() { | 3193 void PaintLayer::setNeedsRepaintInternal() { |
3127 m_needsRepaint = true; | 3194 m_needsRepaint = true; |
3128 setDisplayItemsUncached(); // Invalidate as a display item client. | 3195 setDisplayItemsUncached(); // Invalidate as a display item client. |
3129 } | 3196 } |
3130 | 3197 |
3131 void PaintLayer::markCompositingContainerChainForNeedsRepaint() { | 3198 void PaintLayer::markCompositingContainerChainForNeedsRepaint() { |
3132 // Need to access compositingState(). We've ensured correct flag setting when
compositingState() changes. | 3199 // Need to access compositingState(). We've ensured correct flag setting when |
| 3200 // compositingState() changes. |
3133 DisableCompositingQueryAsserts disabler; | 3201 DisableCompositingQueryAsserts disabler; |
3134 | 3202 |
3135 PaintLayer* layer = this; | 3203 PaintLayer* layer = this; |
3136 while (true) { | 3204 while (true) { |
3137 if (layer->compositingState() == PaintsIntoOwnBacking) | 3205 if (layer->compositingState() == PaintsIntoOwnBacking) |
3138 return; | 3206 return; |
3139 if (CompositedLayerMapping* groupedMapping = layer->groupedMapping()) { | 3207 if (CompositedLayerMapping* groupedMapping = layer->groupedMapping()) { |
3140 // TODO(wkorman): As we clean up the CompositedLayerMapping needsRepaint l
ogic to | 3208 // TODO(wkorman): As we clean up the CompositedLayerMapping needsRepaint |
3141 // delegate to scrollbars, we may be able to remove the line below as well
. | 3209 // logic to delegate to scrollbars, we may be able to remove the line |
| 3210 // below as well. |
3142 groupedMapping->owningLayer().setNeedsRepaint(); | 3211 groupedMapping->owningLayer().setNeedsRepaint(); |
3143 return; | 3212 return; |
3144 } | 3213 } |
3145 | 3214 |
3146 PaintLayer* container = layer->compositingContainer(); | 3215 PaintLayer* container = layer->compositingContainer(); |
3147 if (!container) { | 3216 if (!container) { |
3148 LayoutItem owner = layer->layoutObject()->frame()->ownerLayoutItem(); | 3217 LayoutItem owner = layer->layoutObject()->frame()->ownerLayoutItem(); |
3149 if (owner.isNull()) | 3218 if (owner.isNull()) |
3150 break; | 3219 break; |
3151 container = owner.enclosingLayer(); | 3220 container = owner.enclosingLayer(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3207 } | 3276 } |
3208 | 3277 |
3209 void showLayerTree(const blink::LayoutObject* layoutObject) { | 3278 void showLayerTree(const blink::LayoutObject* layoutObject) { |
3210 if (!layoutObject) { | 3279 if (!layoutObject) { |
3211 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); | 3280 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); |
3212 return; | 3281 return; |
3213 } | 3282 } |
3214 showLayerTree(layoutObject->enclosingLayer()); | 3283 showLayerTree(layoutObject->enclosingLayer()); |
3215 } | 3284 } |
3216 #endif | 3285 #endif |
OLD | NEW |