| 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 |