1 /* 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 3 * 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 5 * 6 * Other contributors: 7 * Robert O'Callahan <roc+@cs.cmu.edu> 8 * David Baron <dbaron (at) fas.harvard.edu> 9 * Christian Biesinger <cbiesinger (at) web.de> 10 * Randall Jesup <rjesup (at) wgate.com> 11 * Roland Mainz <roland.mainz (at) informatik.med.uni-giessen.de> 12 * Josh Soref <timeless (at) mac.com> 13 * Boris Zbarsky <bzbarsky (at) mit.edu> 14 * 15 * This library is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU Lesser General Public 17 * License as published by the Free Software Foundation; either 18 * version 2.1 of the License, or (at your option) any later version. 19 * 20 * This library is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 * Lesser General Public License for more details. 24 * 25 * 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 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 28 * 29 * 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 * 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 * (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 * 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 * version of this file under the LGPL, indicate your decision by 38 * deletingthe provisions above and replace them with the notice and 39 * other provisions required by the MPL or the GPL, as the case may be. 40 * If you do not delete the provisions above, a recipient may use your 41 * version of this file under any of the LGPL, the MPL or the GPL. 42 */ 43 44 #include "config.h" 45 #include "core/rendering/RenderLayer.h" 46 47 #include "core/CSSPropertyNames.h" 48 #include "core/HTMLNames.h" 49 #include "core/css/PseudoStyleRequest.h" 50 #include "core/dom/Document.h" 51 #include "core/dom/shadow/ShadowRoot.h" 52 #include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h" 53 #include "core/frame/FrameView.h" 54 #include "core/frame/LocalFrame.h" 55 #include "core/frame/Settings.h" 56 #include "core/html/HTMLFrameElement.h" 57 #include "core/page/Page.h" 58 #include "core/page/scrolling/ScrollingCoordinator.h" 59 #include "core/rendering/ColumnInfo.h" 60 #include "core/rendering/FilterEffectRenderer.h" 61 #include "core/rendering/HitTestRequest.h" 62 #include "core/rendering/HitTestResult.h" 63 #include "core/rendering/HitTestingTransformState.h" 64 #include "core/rendering/RenderFlowThread.h" 65 #include "core/rendering/RenderGeometryMap.h" 66 #include "core/rendering/RenderInline.h" 67 #include "core/rendering/RenderPart.h" 68 #include "core/rendering/RenderReplica.h" 69 #include "core/rendering/RenderScrollbar.h" 70 #include "core/rendering/RenderScrollbarPart.h" 71 #include "core/rendering/RenderTreeAsText.h" 72 #include "core/rendering/RenderView.h" 73 #include "core/rendering/compositing/CompositedLayerMapping.h" 74 #include "core/rendering/compositing/RenderLayerCompositor.h" 75 #include "core/rendering/svg/ReferenceFilterBuilder.h" 76 #include "core/rendering/svg/RenderSVGResourceClipper.h" 77 #include "platform/LengthFunctions.h" 78 #include "platform/Partitions.h" 79 #include "platform/RuntimeEnabledFeatures.h" 80 #include "platform/TraceEvent.h" 81 #include "platform/geometry/FloatPoint3D.h" 82 #include "platform/geometry/FloatRect.h" 83 #include "platform/geometry/TransformState.h" 84 #include "platform/graphics/GraphicsContextStateSaver.h" 85 #include "platform/graphics/filters/ReferenceFilter.h" 86 #include "platform/graphics/filters/SourceGraphic.h" 87 #include "platform/transforms/ScaleTransformOperation.h" 88 #include "platform/transforms/TransformationMatrix.h" 89 #include "platform/transforms/TranslateTransformOperation.h" 90 #include "public/platform/Platform.h" 91 #include "wtf/StdLibExtras.h" 92 #include "wtf/text/CString.h" 93 94 namespace blink { 95 96 namespace { 97 98 static CompositingQueryMode gCompositingQueryMode = 99 CompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases; 100 101 } // namespace 102 103 using namespace HTMLNames; 104 105 RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type) 106 : m_layerType(type) 107 , m_hasSelfPaintingLayerDescendant(false) 108 , m_hasSelfPaintingLayerDescendantDirty(false) 109 , m_isRootLayer(renderer->isRenderView()) 110 , m_usedTransparency(false) 111 , m_visibleContentStatusDirty(true) 112 , m_hasVisibleContent(false) 113 , m_visibleDescendantStatusDirty(false) 114 , m_hasVisibleDescendant(false) 115 , m_hasVisibleNonLayerContent(false) 116 , m_isPaginated(false) 117 , m_3DTransformedDescendantStatusDirty(true) 118 , m_has3DTransformedDescendant(false) 119 , m_containsDirtyOverlayScrollbars(false) 120 , m_hasFilterInfo(false) 121 , m_needsAncestorDependentCompositingInputsUpdate(true) 122 , m_needsDescendantDependentCompositingInputsUpdate(true) 123 , m_childNeedsCompositingInputsUpdate(true) 124 , m_hasCompositingDescendant(false) 125 , m_hasNonCompositedChild(false) 126 , m_shouldIsolateCompositedDescendants(false) 127 , m_lostGroupedMapping(false) 128 , m_renderer(renderer) 129 , m_parent(0) 130 , m_previous(0) 131 , m_next(0) 132 , m_first(0) 133 , m_last(0) 134 , m_staticInlinePosition(0) 135 , m_staticBlockPosition(0) 136 , m_enclosingPaginationLayer(0) 137 , m_potentialCompositingReasonsFromStyle(CompositingReasonNone) 138 , m_compositingReasons(CompositingReasonNone) 139 , m_groupedMapping(0) 140 , m_clipper(*renderer) 141 { 142 updateStackingNode(); 143 144 m_isSelfPaintingLayer = shouldBeSelfPaintingLayer(); 145 146 if (!renderer->slowFirstChild() && renderer->style()) { 147 m_visibleContentStatusDirty = false; 148 m_hasVisibleContent = renderer->style()->visibility() == VISIBLE; 149 } 150 151 updateScrollableArea(); 152 } 153 154 RenderLayer::~RenderLayer() 155 { 156 if (renderer()->frame() && renderer()->frame()->page()) { 157 if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->page()->scrollingCoordinator()) 158 scrollingCoordinator->willDestroyRenderLayer(this); 159 } 160 161 removeFilterInfoIfNeeded(); 162 163 if (groupedMapping()) { 164 DisableCompositingQueryAsserts disabler; 165 groupedMapping()->removeRenderLayerFromSquashingGraphicsLayer(this); 166 setGroupedMapping(0); 167 } 168 169 // Child layers will be deleted by their corresponding render objects, so 170 // we don't need to delete them ourselves. 171 172 clearCompositedLayerMapping(true); 173 174 if (m_reflectionInfo) 175 m_reflectionInfo->destroy(); 176 } 177 178 String RenderLayer::debugName() const 179 { 180 if (isReflection()) { 181 return renderer()->parent()->debugName() + " (reflection)"; 182 } 183 return renderer()->debugName(); 184 } 185 186 RenderLayerCompositor* RenderLayer::compositor() const 187 { 188 if (!renderer()->view()) 189 return 0; 190 return renderer()->view()->compositor(); 191 } 192 193 void RenderLayer::contentChanged(ContentChangeType changeType) 194 { 195 // updateLayerCompositingState will query compositingReasons for accelerated overflow scrolling. 196 // This is tripped by LayoutTests/compositing/content-changed-chicken-egg.html 197 DisableCompositingQueryAsserts disabler; 198 199 if (changeType == CanvasChanged) 200 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange); 201 202 if (changeType == CanvasContextChanged) { 203 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange); 204 205 // Although we're missing test coverage, we need to call 206 // GraphicsLayer::setContentsToPlatformLayer with the new platform 207 // layer for this canvas. 208 // See http://crbug.com/349195 209 if (hasCompositedLayerMapping()) 210 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); 211 } 212 213 if (m_compositedLayerMapping) 214 m_compositedLayerMapping->contentChanged(changeType); 215 } 216 217 bool RenderLayer::paintsWithFilters() const 218 { 219 if (!renderer()->hasFilter()) 220 return false; 221 222 // https://code.google.com/p/chromium/issues/detail?id=343759 223 DisableCompositingQueryAsserts disabler; 224 return !m_compositedLayerMapping || compositingState() != PaintsIntoOwnBacking; 225 } 226 227 LayoutSize RenderLayer::subpixelAccumulation() const 228 { 229 return m_subpixelAccumulation; 230 } 231 232 void RenderLayer::setSubpixelAccumulation(const LayoutSize& size) 233 { 234 m_subpixelAccumulation = size; 235 } 236 237 void RenderLayer::updateLayerPositionsAfterLayout() 238 { 239 TRACE_EVENT0("blink", "RenderLayer::updateLayerPositionsAfterLayout"); 240 241 m_clipper.clearClipRectsIncludingDescendants(); 242 updateLayerPositionRecursive(); 243 244 { 245 // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues 246 // https://code.google.com/p/chromium/issues/detail?id=343756 247 DisableCompositingQueryAsserts disabler; 248 bool needsPaginationUpdate = isPaginated() || enclosingPaginationLayer(); 249 updatePaginationRecursive(needsPaginationUpdate); 250 } 251 } 252 253 void RenderLayer::updateLayerPositionRecursive() 254 { 255 if (m_reflectionInfo) 256 m_reflectionInfo->reflection()->layout(); 257 258 // FIXME: We should be able to remove this call because we don't care about 259 // any descendant-dependent flags, but code somewhere else is reading these 260 // flags and depending on us to update them. 261 updateDescendantDependentFlags(); 262 263 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 264 child->updateLayerPositionRecursive(); 265 } 266 267 void RenderLayer::updateHasSelfPaintingLayerDescendant() const 268 { 269 ASSERT(m_hasSelfPaintingLayerDescendantDirty); 270 271 m_hasSelfPaintingLayerDescendant = false; 272 273 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { 274 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) { 275 m_hasSelfPaintingLayerDescendant = true; 276 break; 277 } 278 } 279 280 m_hasSelfPaintingLayerDescendantDirty = false; 281 } 282 283 void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus() 284 { 285 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 286 layer->m_hasSelfPaintingLayerDescendantDirty = true; 287 // If we have reached a self-painting layer, we know our parent should have a self-painting descendant 288 // in this case, there is no need to dirty our ancestors further. 289 if (layer->isSelfPaintingLayer()) { 290 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->m_hasSelfPaintingLayerDescendant); 291 break; 292 } 293 } 294 } 295 296 bool RenderLayer::scrollsWithViewport() const 297 { 298 return renderer()->style()->position() == FixedPosition && renderer()->containerForFixedPosition() == renderer()->view(); 299 } 300 301 bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const 302 { 303 if (scrollsWithViewport() != other->scrollsWithViewport()) 304 return true; 305 return ancestorScrollingLayer() != other->ancestorScrollingLayer(); 306 } 307 308 void RenderLayer::updateTransformationMatrix() 309 { 310 if (m_transform) { 311 RenderBox* box = renderBox(); 312 ASSERT(box); 313 m_transform->makeIdentity(); 314 box->style()->applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin); 315 makeMatrixRenderable(*m_transform, compositor()->hasAcceleratedCompositing()); 316 } 317 } 318 319 void RenderLayer::updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle) 320 { 321 if (oldStyle && newStyle->transformDataEquivalent(*oldStyle)) 322 return; 323 324 // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set, 325 // so check style too. 326 bool hasTransform = renderer()->hasTransform() && newStyle->hasTransform(); 327 bool had3DTransform = has3DTransform(); 328 329 bool hadTransform = m_transform; 330 if (hasTransform != hadTransform) { 331 if (hasTransform) 332 m_transform = adoptPtr(new TransformationMatrix); 333 else 334 m_transform.clear(); 335 336 // Layers with transforms act as clip rects roots, so clear the cached clip rects here. 337 m_clipper.clearClipRectsIncludingDescendants(); 338 } else if (hasTransform) { 339 m_clipper.clearClipRectsIncludingDescendants(AbsoluteClipRects); 340 } 341 342 updateTransformationMatrix(); 343 344 if (had3DTransform != has3DTransform()) 345 dirty3DTransformedDescendantStatus(); 346 } 347 348 static RenderLayer* enclosingLayerForContainingBlock(RenderLayer* layer) 349 { 350 if (RenderObject* containingBlock = layer->renderer()->containingBlock()) 351 return containingBlock->enclosingLayer(); 352 return 0; 353 } 354 355 RenderLayer* RenderLayer::renderingContextRoot() 356 { 357 RenderLayer* renderingContext = 0; 358 359 if (shouldPreserve3D()) 360 renderingContext = this; 361 362 for (RenderLayer* current = enclosingLayerForContainingBlock(this); current && current->shouldPreserve3D(); current = enclosingLayerForContainingBlock(current)) 363 renderingContext = current; 364 365 return renderingContext; 366 } 367 368 TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const 369 { 370 if (!m_transform) 371 return TransformationMatrix(); 372 373 // m_transform includes transform-origin, so we need to recompute the transform here. 374 if (applyOrigin == RenderStyle::ExcludeTransformOrigin) { 375 RenderBox* box = renderBox(); 376 TransformationMatrix currTransform; 377 box->style()->applyTransform(currTransform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin); 378 makeMatrixRenderable(currTransform, compositor()->hasAcceleratedCompositing()); 379 return currTransform; 380 } 381 382 return *m_transform; 383 } 384 385 TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const 386 { 387 if (!m_transform) 388 return TransformationMatrix(); 389 390 if (paintBehavior & PaintBehaviorFlattenCompositingLayers) { 391 TransformationMatrix matrix = *m_transform; 392 makeMatrixRenderable(matrix, false /* flatten 3d */); 393 return matrix; 394 } 395 396 return *m_transform; 397 } 398 399 RenderLayer* RenderLayer::enclosingOverflowClipLayer(IncludeSelfOrNot includeSelf) const 400 { 401 const RenderLayer* layer = (includeSelf == IncludeSelf) ? this : parent(); 402 while (layer) { 403 if (layer->renderer()->hasOverflowClip()) 404 return const_cast<RenderLayer*>(layer); 405 406 layer = layer->parent(); 407 } 408 return 0; 409 } 410 411 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer) 412 { 413 RenderView* view = renderer->view(); 414 RenderLayerModelObject* prevBlock = renderer; 415 RenderBlock* containingBlock; 416 for (containingBlock = renderer->containingBlock(); 417 containingBlock && containingBlock != view && containingBlock != ancestorColumnsRenderer; 418 containingBlock = containingBlock->containingBlock()) 419 prevBlock = containingBlock; 420 421 // If the columns block wasn't in our containing block chain, then we aren't paginated by it. 422 if (containingBlock != ancestorColumnsRenderer) 423 return false; 424 425 // If the previous block is absolutely positioned, then we can't be paginated by the columns block. 426 if (prevBlock->isOutOfFlowPositioned()) 427 return false; 428 429 // Otherwise we are paginated by the columns block. 430 return true; 431 } 432 433 bool RenderLayer::useRegionBasedColumns() const 434 { 435 return renderer()->document().regionBasedColumnsEnabled(); 436 } 437 438 void RenderLayer::updatePaginationRecursive(bool needsPaginationUpdate) 439 { 440 m_isPaginated = false; 441 m_enclosingPaginationLayer = 0; 442 443 if (useRegionBasedColumns() && renderer()->isRenderFlowThread()) 444 needsPaginationUpdate = true; 445 446 if (needsPaginationUpdate) 447 updatePagination(); 448 449 if (renderer()->hasColumns()) 450 needsPaginationUpdate = true; 451 452 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 453 child->updatePaginationRecursive(needsPaginationUpdate); 454 } 455 456 void RenderLayer::updatePagination() 457 { 458 if (compositingState() != NotComposited || !parent()) 459 return; // FIXME: We will have to deal with paginated compositing layers someday. 460 // FIXME: For now the RenderView can't be paginated. Eventually printing will move to a model where it is though. 461 462 // The main difference between the paginated booleans for the old column code and the new column code 463 // is that each paginated layer has to paint on its own with the new code. There is no 464 // recurring into child layers. This means that the m_isPaginated bits for the new column code can't just be set on 465 // "roots" that get split and paint all their descendants. Instead each layer has to be checked individually and 466 // genuinely know if it is going to have to split itself up when painting only its contents (and not any other descendant 467 // layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back 468 // to that layer easily. 469 bool regionBasedColumnsUsed = useRegionBasedColumns(); 470 if (regionBasedColumnsUsed && renderer()->isRenderFlowThread()) { 471 m_enclosingPaginationLayer = this; 472 return; 473 } 474 475 if (m_stackingNode->isNormalFlowOnly()) { 476 if (regionBasedColumnsUsed) { 477 // Content inside a transform is not considered to be paginated, since we simply 478 // paint the transform multiple times in each column, so we don't have to use 479 // fragments for the transformed content. 480 m_enclosingPaginationLayer = parent()->enclosingPaginationLayer(); 481 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform()) 482 m_enclosingPaginationLayer = 0; 483 } else { 484 m_isPaginated = parent()->renderer()->hasColumns(); 485 } 486 return; 487 } 488 489 // For the new columns code, we want to walk up our containing block chain looking for an enclosing layer. Once 490 // we find one, then we just check its pagination status. 491 if (regionBasedColumnsUsed) { 492 RenderView* view = renderer()->view(); 493 RenderBlock* containingBlock; 494 for (containingBlock = renderer()->containingBlock(); 495 containingBlock && containingBlock != view; 496 containingBlock = containingBlock->containingBlock()) { 497 if (containingBlock->hasLayer()) { 498 // Content inside a transform is not considered to be paginated, since we simply 499 // paint the transform multiple times in each column, so we don't have to use 500 // fragments for the transformed content. 501 m_enclosingPaginationLayer = containingBlock->layer()->enclosingPaginationLayer(); 502 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform()) 503 m_enclosingPaginationLayer = 0; 504 return; 505 } 506 } 507 return; 508 } 509 510 // If we're not normal flow, then we need to look for a multi-column object between us and our stacking container. 511 RenderLayerStackingNode* ancestorStackingContextNode = m_stackingNode->ancestorStackingContextNode(); 512 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) { 513 if (curr->renderer()->hasColumns()) { 514 m_isPaginated = checkContainingBlockChainForPagination(renderer(), curr->renderBox()); 515 return; 516 } 517 if (curr->stackingNode() == ancestorStackingContextNode) 518 return; 519 } 520 } 521 522 LayoutPoint RenderLayer::positionFromPaintInvalidationBacking(const RenderObject* renderObject, const RenderLayerModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) 523 { 524 FloatPoint point = renderObject->localToContainerPoint(FloatPoint(), paintInvalidationContainer, 0, 0, paintInvalidationState); 525 526 // FIXME: Eventually we are going to unify coordinates in GraphicsLayer space. 527 if (paintInvalidationContainer && paintInvalidationContainer->layer()->groupedMapping()) 528 mapPointToPaintBackingCoordinates(paintInvalidationContainer, point); 529 530 return LayoutPoint(point); 531 } 532 533 void RenderLayer::mapPointToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, FloatPoint& point) 534 { 535 RenderLayer* paintInvalidationLayer = paintInvalidationContainer->layer(); 536 if (!paintInvalidationLayer->groupedMapping()) { 537 point.move(paintInvalidationLayer->compositedLayerMapping()->contentOffsetInCompositingLayer()); 538 return; 539 } 540 541 RenderLayerModelObject* transformedAncestor = paintInvalidationLayer->enclosingTransformedAncestor()->renderer(); 542 if (!transformedAncestor) 543 return; 544 545 // |paintInvalidationContainer| may have a local 2D transform on it, so take that into account when mapping into the space of the 546 // transformed ancestor. 547 point = paintInvalidationContainer->localToContainerPoint(point, transformedAncestor); 548 549 point.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromTransformedAncestor()); 550 } 551 552 void RenderLayer::mapRectToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect) 553 { 554 RenderLayer* paintInvalidationLayer = paintInvalidationContainer->layer(); 555 if (!paintInvalidationLayer->groupedMapping()) { 556 rect.move(paintInvalidationLayer->compositedLayerMapping()->contentOffsetInCompositingLayer()); 557 return; 558 } 559 560 RenderLayerModelObject* transformedAncestor = paintInvalidationLayer->enclosingTransformedAncestor()->renderer(); 561 if (!transformedAncestor) 562 return; 563 564 // |paintInvalidationContainer| may have a local 2D transform on it, so take that into account when mapping into the space of the 565 // transformed ancestor. 566 rect = LayoutRect(paintInvalidationContainer->localToContainerQuad(FloatRect(rect), transformedAncestor).boundingBox()); 567 568 rect.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromTransformedAncestor()); 569 } 570 571 void RenderLayer::mapRectToPaintInvalidationBacking(const RenderObject* renderObject, const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, const PaintInvalidationState* paintInvalidationState) 572 { 573 if (!paintInvalidationContainer->layer()->groupedMapping()) { 574 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, paintInvalidationState); 575 return; 576 } 577 578 // This code adjusts the paint invalidation rectangle to be in the space of the transformed ancestor of the grouped (i.e. squashed) 579 // layer. This is because all layers that squash together need to issue paint invalidations w.r.t. a single container that is 580 // an ancestor of all of them, in order to properly take into account any local transforms etc. 581 // FIXME: remove this special-case code that works around the paint invalidation code structure. 582 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, paintInvalidationState); 583 584 mapRectToPaintBackingCoordinates(paintInvalidationContainer, rect); 585 } 586 587 LayoutRect RenderLayer::computePaintInvalidationRect(const RenderObject* renderObject, const RenderLayer* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) 588 { 589 if (!paintInvalidationContainer->groupedMapping()) 590 return renderObject->computePaintInvalidationRect(paintInvalidationContainer->renderer(), paintInvalidationState); 591 592 LayoutRect rect = renderObject->clippedOverflowRectForPaintInvalidation(paintInvalidationContainer->renderer(), paintInvalidationState); 593 mapRectToPaintBackingCoordinates(paintInvalidationContainer->renderer(), rect); 594 return rect; 595 } 596 597 void RenderLayer::dirtyVisibleContentStatus() 598 { 599 m_visibleContentStatusDirty = true; 600 if (parent()) 601 parent()->dirtyAncestorChainVisibleDescendantStatus(); 602 } 603 604 void RenderLayer::potentiallyDirtyVisibleContentStatus(EVisibility visibility) 605 { 606 if (m_visibleContentStatusDirty) 607 return; 608 if (hasVisibleContent() == (visibility == VISIBLE)) 609 return; 610 dirtyVisibleContentStatus(); 611 } 612 613 void RenderLayer::dirtyAncestorChainVisibleDescendantStatus() 614 { 615 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 616 if (layer->m_visibleDescendantStatusDirty) 617 break; 618 619 layer->m_visibleDescendantStatusDirty = true; 620 } 621 } 622 623 // FIXME: this is quite brute-force. We could be more efficient if we were to 624 // track state and update it as appropriate as changes are made in the Render tree. 625 void RenderLayer::updateScrollingStateAfterCompositingChange() 626 { 627 TRACE_EVENT0("blink", "RenderLayer::updateScrollingStateAfterCompositingChange"); 628 m_hasVisibleNonLayerContent = false; 629 for (RenderObject* r = renderer()->slowFirstChild(); r; r = r->nextSibling()) { 630 if (!r->hasLayer()) { 631 m_hasVisibleNonLayerContent = true; 632 break; 633 } 634 } 635 636 m_hasNonCompositedChild = false; 637 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { 638 if (child->compositingState() == NotComposited || child->compositingState() == HasOwnBackingButPaintsIntoAncestor) { 639 m_hasNonCompositedChild = true; 640 return; 641 } 642 } 643 } 644 645 // The descendant-dependent flags system is badly broken because we clean dirty 646 // bits in upward tree walks, which means we need to call updateDescendantDependentFlags 647 // at every node in the tree to fully clean all the dirty bits. While we'll in 648 // the process of fixing this issue, updateDescendantDependentFlagsForEntireSubtree 649 // provides a big hammer for actually cleaning all the dirty bits in a subtree. 650 // 651 // FIXME: Remove this function once the descendant-dependent flags system keeps 652 // its dirty bits scoped to subtrees. 653 void RenderLayer::updateDescendantDependentFlagsForEntireSubtree() 654 { 655 updateDescendantDependentFlags(); 656 657 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 658 child->updateDescendantDependentFlagsForEntireSubtree(); 659 } 660 661 void RenderLayer::updateDescendantDependentFlags() 662 { 663 if (m_visibleDescendantStatusDirty) { 664 m_hasVisibleDescendant = false; 665 666 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { 667 child->updateDescendantDependentFlags(); 668 669 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) { 670 m_hasVisibleDescendant = true; 671 break; 672 } 673 } 674 675 m_visibleDescendantStatusDirty = false; 676 } 677 678 if (m_visibleContentStatusDirty) { 679 bool previouslyHasVisibleContent = m_hasVisibleContent; 680 if (renderer()->style()->visibility() == VISIBLE) 681 m_hasVisibleContent = true; 682 else { 683 // layer may be hidden but still have some visible content, check for this 684 m_hasVisibleContent = false; 685 RenderObject* r = renderer()->slowFirstChild(); 686 while (r) { 687 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) { 688 m_hasVisibleContent = true; 689 break; 690 } 691 RenderObject* rendererFirstChild = r->slowFirstChild(); 692 if (rendererFirstChild && !r->hasLayer()) 693 r = rendererFirstChild; 694 else if (r->nextSibling()) 695 r = r->nextSibling(); 696 else { 697 do { 698 r = r->parent(); 699 if (r == renderer()) 700 r = 0; 701 } while (r && !r->nextSibling()); 702 if (r) 703 r = r->nextSibling(); 704 } 705 } 706 } 707 m_visibleContentStatusDirty = false; 708 709 if (hasVisibleContent() != previouslyHasVisibleContent) { 710 setNeedsCompositingInputsUpdate(); 711 // We need to tell m_renderer to recheck its rect because we 712 // pretend that invisible RenderObjects have 0x0 rects. Changing 713 // visibility therefore changes our rect and we need to visit 714 // this RenderObject during the invalidateTreeIfNeeded walk. 715 m_renderer->setMayNeedPaintInvalidation(true); 716 } 717 } 718 } 719 720 void RenderLayer::dirty3DTransformedDescendantStatus() 721 { 722 RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContextNode(); 723 if (!stackingNode) 724 return; 725 726 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true; 727 728 // This propagates up through preserve-3d hierarchies to the enclosing flattening layer. 729 // Note that preserves3D() creates stacking context, so we can just run up the stacking containers. 730 while (stackingNode && stackingNode->layer()->preserves3D()) { 731 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true; 732 stackingNode = stackingNode->ancestorStackingContextNode(); 733 } 734 } 735 736 // Return true if this layer or any preserve-3d descendants have 3d. 737 bool RenderLayer::update3DTransformedDescendantStatus() 738 { 739 if (m_3DTransformedDescendantStatusDirty) { 740 m_has3DTransformedDescendant = false; 741 742 m_stackingNode->updateZOrderLists(); 743 744 // Transformed or preserve-3d descendants can only be in the z-order lists, not 745 // in the normal flow list, so we only need to check those. 746 RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), PositiveZOrderChildren | NegativeZOrderChildren); 747 while (RenderLayerStackingNode* node = iterator.next()) 748 m_has3DTransformedDescendant |= node->layer()->update3DTransformedDescendantStatus(); 749 750 m_3DTransformedDescendantStatusDirty = false; 751 } 752 753 // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs 754 // the m_has3DTransformedDescendant set. 755 if (preserves3D()) 756 return has3DTransform() || m_has3DTransformedDescendant; 757 758 return has3DTransform(); 759 } 760 761 IntSize RenderLayer::size() const 762 { 763 if (renderer()->isInline() && renderer()->isRenderInline()) 764 return toRenderInline(renderer())->linesBoundingBox().size(); 765 766 // FIXME: Is snapping the size really needed here? 767 if (RenderBox* box = renderBox()) 768 return pixelSnappedIntSize(box->size(), box->location()); 769 770 return IntSize(); 771 } 772 773 LayoutPoint RenderLayer::location() const 774 { 775 LayoutPoint localPoint; 776 LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done. 777 778 if (renderer()->isInline() && renderer()->isRenderInline()) { 779 RenderInline* inlineFlow = toRenderInline(renderer()); 780 IntRect lineBox = inlineFlow->linesBoundingBox(); 781 inlineBoundingBoxOffset = toSize(lineBox.location()); 782 localPoint += inlineBoundingBoxOffset; 783 } else if (RenderBox* box = renderBox()) { 784 localPoint += box->topLeftLocationOffset(); 785 } 786 787 if (!renderer()->isOutOfFlowPositioned() && renderer()->parent()) { 788 // We must adjust our position by walking up the render tree looking for the 789 // nearest enclosing object with a layer. 790 RenderObject* curr = renderer()->parent(); 791 while (curr && !curr->hasLayer()) { 792 if (curr->isBox() && !curr->isTableRow()) { 793 // Rows and cells share the same coordinate space (that of the section). 794 // Omit them when computing our xpos/ypos. 795 localPoint += toRenderBox(curr)->topLeftLocationOffset(); 796 } 797 curr = curr->parent(); 798 } 799 if (curr->isBox() && curr->isTableRow()) { 800 // Put ourselves into the row coordinate space. 801 localPoint -= toRenderBox(curr)->topLeftLocationOffset(); 802 } 803 } 804 805 // Subtract our parent's scroll offset. 806 if (renderer()->isOutOfFlowPositioned() && enclosingPositionedAncestor()) { 807 RenderLayer* positionedParent = enclosingPositionedAncestor(); 808 809 // For positioned layers, we subtract out the enclosing positioned layer's scroll offset. 810 if (positionedParent->renderer()->hasOverflowClip()) { 811 LayoutSize offset = positionedParent->renderBox()->scrolledContentOffset(); 812 localPoint -= offset; 813 } 814 815 if (positionedParent->renderer()->isRelPositioned() && positionedParent->renderer()->isRenderInline()) { 816 LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(*toRenderBox(renderer())); 817 localPoint += offset; 818 } 819 } else if (parent()) { 820 // FIXME: This code is very wrong. The compositing system doesn't 821 // understand columns and we're hacking around that fact by faking 822 // the position of the RenderLayers when we think we'll end up being 823 // composited. Hopefully we'll be able to unwind this hack when we 824 // implement multi-column using regions. 825 if (hasStyleDeterminedDirectCompositingReasons()) { 826 // FIXME: Composited layers ignore pagination, so about the best we can do is make sure they're offset into the appropriate column. 827 // They won't split across columns properly. 828 if (!parent()->renderer()->hasColumns() && parent()->renderer()->isDocumentElement() && renderer()->view()->hasColumns()) 829 localPoint += renderer()->view()->columnOffset(localPoint); 830 else 831 localPoint += parent()->renderer()->columnOffset(localPoint); 832 } 833 834 if (parent()->renderer()->hasOverflowClip()) { 835 IntSize scrollOffset = parent()->renderBox()->scrolledContentOffset(); 836 localPoint -= scrollOffset; 837 } 838 } 839 840 localPoint.move(offsetForInFlowPosition()); 841 842 // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers. 843 localPoint -= inlineBoundingBoxOffset; 844 845 return localPoint; 846 } 847 848 const LayoutSize RenderLayer::offsetForInFlowPosition() const 849 { 850 return renderer()->isRelPositioned() ? toRenderBoxModelObject(renderer())->offsetForInFlowPosition() : LayoutSize(); 851 } 852 853 TransformationMatrix RenderLayer::perspectiveTransform() const 854 { 855 if (!renderer()->hasTransform()) 856 return TransformationMatrix(); 857 858 RenderStyle* style = renderer()->style(); 859 if (!style->hasPerspective()) 860 return TransformationMatrix(); 861 862 // Maybe fetch the perspective from the backing? 863 const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect(); 864 const float boxWidth = borderBox.width(); 865 const float boxHeight = borderBox.height(); 866 867 float perspectiveOriginX = floatValueForLength(style->perspectiveOriginX(), boxWidth); 868 float perspectiveOriginY = floatValueForLength(style->perspectiveOriginY(), boxHeight); 869 870 // A perspective origin of 0,0 makes the vanishing point in the center of the element. 871 // We want it to be in the top-left, so subtract half the height and width. 872 perspectiveOriginX -= boxWidth / 2.0f; 873 perspectiveOriginY -= boxHeight / 2.0f; 874 875 TransformationMatrix t; 876 t.translate(perspectiveOriginX, perspectiveOriginY); 877 t.applyPerspective(style->perspective()); 878 t.translate(-perspectiveOriginX, -perspectiveOriginY); 879 880 return t; 881 } 882 883 FloatPoint RenderLayer::perspectiveOrigin() const 884 { 885 if (!renderer()->hasTransform()) 886 return FloatPoint(); 887 888 const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect(); 889 RenderStyle* style = renderer()->style(); 890 891 return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox.width().toFloat()), floatValueForLength(style->perspectiveOriginY(), borderBox.height().toFloat())); 892 } 893 894 static inline bool isFixedPositionedContainer(RenderLayer* layer) 895 { 896 return layer->isRootLayer() || layer->hasTransform(); 897 } 898 899 RenderLayer* RenderLayer::enclosingPositionedAncestor() const 900 { 901 RenderLayer* curr = parent(); 902 while (curr && !curr->isPositionedContainer()) 903 curr = curr->parent(); 904 905 return curr; 906 } 907 908 RenderLayer* RenderLayer::enclosingTransformedAncestor() const 909 { 910 RenderLayer* curr = parent(); 911 while (curr && !curr->isRootLayer() && !curr->renderer()->hasTransform()) 912 curr = curr->parent(); 913 914 return curr; 915 } 916 917 LayoutPoint RenderLayer::computeOffsetFromTransformedAncestor() const 918 { 919 const AncestorDependentCompositingInputs& properties = ancestorDependentCompositingInputs(); 920 921 TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint()); 922 // FIXME: add a test that checks flipped writing mode and ApplyContainerFlip are correct. 923 renderer()->mapLocalToContainer(properties.transformAncestor ? properties.transformAncestor->renderer() : 0, transformState, ApplyContainerFlip); 924 transformState.flatten(); 925 return LayoutPoint(transformState.lastPlanarPoint()); 926 } 927 928 const RenderLayer* RenderLayer::compositingContainer() const 929 { 930 if (stackingNode()->isNormalFlowOnly()) 931 return parent(); 932 if (RenderLayerStackingNode* ancestorStackingNode = stackingNode()->ancestorStackingContextNode()) 933 return ancestorStackingNode->layer(); 934 return 0; 935 } 936 937 bool RenderLayer::isPaintInvalidationContainer() const 938 { 939 return compositingState() == PaintsIntoOwnBacking || compositingState() == PaintsIntoGroupedBacking; 940 } 941 942 // Note: enclosingCompositingLayer does not include squashed layers. Compositing stacking children of squashed layers 943 // receive graphics layers that are parented to the compositing ancestor of the squashed layer. 944 RenderLayer* RenderLayer::enclosingLayerWithCompositedLayerMapping(IncludeSelfOrNot includeSelf) const 945 { 946 ASSERT(isAllowedToQueryCompositingState()); 947 948 if ((includeSelf == IncludeSelf) && compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking) 949 return const_cast<RenderLayer*>(this); 950 951 for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->compositingContainer()) { 952 if (curr->compositingState() != NotComposited && curr->compositingState() != PaintsIntoGroupedBacking) 953 return const_cast<RenderLayer*>(curr); 954 } 955 956 return 0; 957 } 958 959 // Return the enclosingCompositedLayerForPaintInvalidation for the given RenderLayer 960 // including crossing frame boundaries. 961 RenderLayer* RenderLayer::enclosingLayerForPaintInvalidationCrossingFrameBoundaries() const 962 { 963 const RenderLayer* layer = this; 964 RenderLayer* compositedLayer = 0; 965 while (!compositedLayer) { 966 compositedLayer = layer->enclosingLayerForPaintInvalidation(); 967 if (!compositedLayer) { 968 RenderObject* owner = layer->renderer()->frame()->ownerRenderer(); 969 if (!owner) 970 break; 971 layer = owner->enclosingLayer(); 972 } 973 } 974 return compositedLayer; 975 } 976 977 RenderLayer* RenderLayer::enclosingLayerForPaintInvalidation() const 978 { 979 ASSERT(isAllowedToQueryCompositingState()); 980 981 if (isPaintInvalidationContainer()) 982 return const_cast<RenderLayer*>(this); 983 984 for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->compositingContainer()) { 985 if (curr->isPaintInvalidationContainer()) 986 return const_cast<RenderLayer*>(curr); 987 } 988 989 return 0; 990 } 991 992 void RenderLayer::setNeedsCompositingInputsUpdate() 993 { 994 m_needsAncestorDependentCompositingInputsUpdate = true; 995 m_needsDescendantDependentCompositingInputsUpdate = true; 996 997 for (RenderLayer* current = this; current && !current->m_childNeedsCompositingInputsUpdate; current = current->parent()) 998 current->m_childNeedsCompositingInputsUpdate = true; 999 1000 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange); 1001 } 1002 1003 void RenderLayer::updateAncestorDependentCompositingInputs(const AncestorDependentCompositingInputs& compositingInputs) 1004 { 1005 m_ancestorDependentCompositingInputs = compositingInputs; 1006 m_needsAncestorDependentCompositingInputsUpdate = false; 1007 } 1008 1009 void RenderLayer::updateDescendantDependentCompositingInputs(const DescendantDependentCompositingInputs& compositingInputs) 1010 { 1011 m_descendantDependentCompositingInputs = compositingInputs; 1012 m_needsDescendantDependentCompositingInputsUpdate = false; 1013 } 1014 1015 void RenderLayer::didUpdateCompositingInputs() 1016 { 1017 ASSERT(!needsCompositingInputsUpdate()); 1018 m_childNeedsCompositingInputsUpdate = false; 1019 if (m_scrollableArea) 1020 m_scrollableArea->updateNeedsCompositedScrolling(); 1021 } 1022 1023 void RenderLayer::setCompositingReasons(CompositingReasons reasons, CompositingReasons mask) 1024 { 1025 if ((compositingReasons() & mask) == (reasons & mask)) 1026 return; 1027 m_compositingReasons = (reasons & mask) | (compositingReasons() & ~mask); 1028 } 1029 1030 void RenderLayer::setHasCompositingDescendant(bool hasCompositingDescendant) 1031 { 1032 if (m_hasCompositingDescendant == static_cast<unsigned>(hasCompositingDescendant)) 1033 return; 1034 1035 m_hasCompositingDescendant = hasCompositingDescendant; 1036 1037 if (hasCompositedLayerMapping()) 1038 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal); 1039 } 1040 1041 void RenderLayer::setShouldIsolateCompositedDescendants(bool shouldIsolateCompositedDescendants) 1042 { 1043 if (m_shouldIsolateCompositedDescendants == static_cast<unsigned>(shouldIsolateCompositedDescendants)) 1044 return; 1045 1046 m_shouldIsolateCompositedDescendants = shouldIsolateCompositedDescendants; 1047 1048 if (hasCompositedLayerMapping()) 1049 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal); 1050 } 1051 1052 bool RenderLayer::hasAncestorWithFilterOutsets() const 1053 { 1054 for (const RenderLayer* curr = this; curr; curr = curr->parent()) { 1055 RenderLayerModelObject* renderer = curr->renderer(); 1056 if (renderer->style()->hasFilterOutsets()) 1057 return true; 1058 } 1059 return false; 1060 } 1061 1062 RenderLayer* RenderLayer::transparentPaintingAncestor() 1063 { 1064 if (hasCompositedLayerMapping()) 1065 return 0; 1066 1067 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) { 1068 if (curr->hasCompositedLayerMapping()) 1069 return 0; 1070 if (curr->isTransparent()) 1071 return curr; 1072 } 1073 return 0; 1074 } 1075 1076 enum TransparencyClipBoxBehavior { 1077 PaintingTransparencyClipBox, 1078 HitTestingTransparencyClipBox 1079 }; 1080 1081 enum TransparencyClipBoxMode { 1082 DescendantsOfTransparencyClipBox, 1083 RootOfTransparencyClipBox 1084 }; 1085 1086 static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, const LayoutSize& subPixelAccumulation, PaintBehavior = 0); 1087 1088 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer, 1089 TransparencyClipBoxBehavior transparencyBehavior, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior) 1090 { 1091 // If we have a mask, then the clip is limited to the border box area (and there is 1092 // no need to examine child layers). 1093 if (!layer->renderer()->hasMask()) { 1094 // Note: we don't have to walk z-order lists since transparent elements always establish 1095 // a stacking container. This means we can just walk the layer tree directly. 1096 for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) { 1097 if (!layer->reflectionInfo() || layer->reflectionInfo()->reflectionLayer() != curr) 1098 clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, subPixelAccumulation, paintBehavior)); 1099 } 1100 } 1101 1102 // If we have a reflection, then we need to account for that when we push the clip. Reflect our entire 1103 // current transparencyClipBox to catch all child layers. 1104 // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this 1105 // size into the parent layer. 1106 if (layer->renderer()->hasReflection()) { 1107 LayoutPoint delta; 1108 layer->convertToLayerCoords(rootLayer, delta); 1109 clipRect.move(-delta.x(), -delta.y()); 1110 clipRect.unite(layer->renderBox()->reflectedRect(clipRect)); 1111 clipRect.moveBy(delta); 1112 } 1113 } 1114 1115 static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior, 1116 TransparencyClipBoxMode transparencyMode, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior) 1117 { 1118 // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the 1119 // paintDirtyRect, and that should cut down on the amount we have to paint. Still it 1120 // would be better to respect clips. 1121 1122 if (rootLayer != layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer->paintsWithTransform(paintBehavior)) 1123 || (transparencyBehavior == HitTestingTransparencyClipBox && layer->hasTransform()))) { 1124 // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass 1125 // the transformed layer and all of its children. 1126 const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer->enclosingPaginationLayer() : 0; 1127 const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer; 1128 LayoutPoint delta; 1129 layer->convertToLayerCoords(rootLayerForTransform, delta); 1130 1131 delta.move(subPixelAccumulation); 1132 IntPoint pixelSnappedDelta = roundedIntPoint(delta); 1133 TransformationMatrix transform; 1134 transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y()); 1135 transform = transform * *layer->transform(); 1136 1137 // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always 1138 // paints unfragmented. 1139 LayoutRect clipRect = layer->physicalBoundingBox(layer); 1140 expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, subPixelAccumulation, paintBehavior); 1141 layer->renderer()->style()->filterOutsets().expandRect(clipRect); 1142 LayoutRect result = transform.mapRect(clipRect); 1143 if (!paginationLayer) 1144 return result; 1145 1146 // We have to break up the transformed extent across our columns. 1147 // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to 1148 // get our true bounding box. 1149 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer()); 1150 result = enclosingFlowThread->fragmentsBoundingBox(result); 1151 1152 LayoutPoint rootLayerDelta; 1153 paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta); 1154 result.moveBy(rootLayerDelta); 1155 return result; 1156 } 1157 1158 LayoutRect clipRect = layer->physicalBoundingBox(rootLayer); 1159 expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, subPixelAccumulation, paintBehavior); 1160 layer->renderer()->style()->filterOutsets().expandRect(clipRect); 1161 clipRect.move(subPixelAccumulation); 1162 return clipRect; 1163 } 1164 1165 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior) 1166 { 1167 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, subPixelAccumulation, paintBehavior), paintDirtyRect); 1168 } 1169 1170 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior) 1171 { 1172 bool createTransparencyLayerForBlendMode = m_stackingNode->isStackingContext() && hasDescendantWithBlendMode(); 1173 if ((paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency) 1174 return; 1175 1176 RenderLayer* ancestor = transparentPaintingAncestor(); 1177 if (ancestor) 1178 ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior); 1179 1180 if (paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) { 1181 m_usedTransparency = true; 1182 context->save(); 1183 LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior); 1184 context->clip(clipRect); 1185 1186 if (paintsWithBlendMode()) 1187 context->setCompositeOperation(context->compositeOperation(), m_renderer->style()->blendMode()); 1188 1189 context->beginTransparencyLayer(renderer()->opacity()); 1190 1191 if (paintsWithBlendMode()) 1192 context->setCompositeOperation(context->compositeOperation(), WebBlendModeNormal); 1193 #ifdef REVEAL_TRANSPARENCY_LAYERS 1194 context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f)); 1195 context->fillRect(clipRect); 1196 #endif 1197 } 1198 } 1199 1200 void* RenderLayer::operator new(size_t sz) 1201 { 1202 return partitionAlloc(Partitions::getRenderingPartition(), sz); 1203 } 1204 1205 void RenderLayer::operator delete(void* ptr) 1206 { 1207 partitionFree(ptr); 1208 } 1209 1210 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild) 1211 { 1212 RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild(); 1213 if (prevSibling) { 1214 child->setPreviousSibling(prevSibling); 1215 prevSibling->setNextSibling(child); 1216 ASSERT(prevSibling != child); 1217 } else 1218 setFirstChild(child); 1219 1220 if (beforeChild) { 1221 beforeChild->setPreviousSibling(child); 1222 child->setNextSibling(beforeChild); 1223 ASSERT(beforeChild != child); 1224 } else 1225 setLastChild(child); 1226 1227 child->m_parent = this; 1228 1229 setNeedsCompositingInputsUpdate(); 1230 1231 if (child->stackingNode()->isNormalFlowOnly()) 1232 m_stackingNode->dirtyNormalFlowList(); 1233 1234 if (!child->stackingNode()->isNormalFlowOnly() || child->firstChild()) { 1235 // Dirty the z-order list in which we are contained. The ancestorStackingContextNode() can be null in the 1236 // case where we're building up generated content layers. This is ok, since the lists will start 1237 // off dirty in that case anyway. 1238 child->stackingNode()->dirtyStackingContextZOrderLists(); 1239 } 1240 1241 dirtyAncestorChainVisibleDescendantStatus(); 1242 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 1243 1244 child->updateDescendantDependentFlags(); 1245 } 1246 1247 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild) 1248 { 1249 if (oldChild->previousSibling()) 1250 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); 1251 if (oldChild->nextSibling()) 1252 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()); 1253 1254 if (m_first == oldChild) 1255 m_first = oldChild->nextSibling(); 1256 if (m_last == oldChild) 1257 m_last = oldChild->previousSibling(); 1258 1259 if (oldChild->stackingNode()->isNormalFlowOnly()) 1260 m_stackingNode->dirtyNormalFlowList(); 1261 if (!oldChild->stackingNode()->isNormalFlowOnly() || oldChild->firstChild()) { 1262 // Dirty the z-order list in which we are contained. When called via the 1263 // reattachment process in removeOnlyThisLayer, the layer may already be disconnected 1264 // from the main layer tree, so we need to null-check the 1265 // |stackingContext| value. 1266 oldChild->stackingNode()->dirtyStackingContextZOrderLists(); 1267 } 1268 1269 if (renderer()->style()->visibility() != VISIBLE) 1270 dirtyVisibleContentStatus(); 1271 1272 oldChild->setPreviousSibling(0); 1273 oldChild->setNextSibling(0); 1274 oldChild->m_parent = 0; 1275 1276 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 1277 1278 oldChild->updateDescendantDependentFlags(); 1279 1280 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) 1281 dirtyAncestorChainVisibleDescendantStatus(); 1282 1283 return oldChild; 1284 } 1285 1286 void RenderLayer::removeOnlyThisLayer() 1287 { 1288 if (!m_parent) 1289 return; 1290 1291 m_clipper.clearClipRectsIncludingDescendants(); 1292 1293 RenderLayer* nextSib = nextSibling(); 1294 1295 // Remove the child reflection layer before moving other child layers. 1296 // The reflection layer should not be moved to the parent. 1297 if (m_reflectionInfo) 1298 removeChild(m_reflectionInfo->reflectionLayer()); 1299 1300 // Now walk our kids and reattach them to our parent. 1301 RenderLayer* current = m_first; 1302 while (current) { 1303 RenderLayer* next = current->nextSibling(); 1304 removeChild(current); 1305 m_parent->addChild(current, nextSib); 1306 1307 // FIXME: We should call a specialized version of this function. 1308 current->updateLayerPositionsAfterLayout(); 1309 current = next; 1310 } 1311 1312 // Remove us from the parent. 1313 m_parent->removeChild(this); 1314 m_renderer->destroyLayer(); 1315 } 1316 1317 void RenderLayer::insertOnlyThisLayer() 1318 { 1319 if (!m_parent && renderer()->parent()) { 1320 // We need to connect ourselves when our renderer() has a parent. 1321 // Find our enclosingLayer and add ourselves. 1322 RenderLayer* parentLayer = renderer()->parent()->enclosingLayer(); 1323 ASSERT(parentLayer); 1324 RenderLayer* beforeChild = !parentLayer->reflectionInfo() || parentLayer->reflectionInfo()->reflectionLayer() != this ? renderer()->parent()->findNextLayer(parentLayer, renderer()) : 0; 1325 parentLayer->addChild(this, beforeChild); 1326 } 1327 1328 // Remove all descendant layers from the hierarchy and add them to the new position. 1329 for (RenderObject* curr = renderer()->slowFirstChild(); curr; curr = curr->nextSibling()) 1330 curr->moveLayers(m_parent, this); 1331 1332 // Clear out all the clip rects. 1333 m_clipper.clearClipRectsIncludingDescendants(); 1334 } 1335 1336 // Returns the layer reached on the walk up towards the ancestor. 1337 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location) 1338 { 1339 ASSERT(ancestorLayer != layer); 1340 1341 const RenderLayerModelObject* renderer = layer->renderer(); 1342 EPosition position = renderer->style()->position(); 1343 1344 // FIXME: Special casing RenderFlowThread so much for fixed positioning here is not great. 1345 RenderFlowThread* fixedFlowThreadContainer = position == FixedPosition ? renderer->flowThreadContainingBlock() : 0; 1346 if (fixedFlowThreadContainer && !fixedFlowThreadContainer->isOutOfFlowPositioned()) 1347 fixedFlowThreadContainer = 0; 1348 1349 // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread 1350 // may need to be revisited in a future patch. 1351 // If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute, 1352 // since localToAbsolute maps the coordinates from flow thread to regions coordinates and regions can be 1353 // positioned in a completely different place in the viewport (RenderView). 1354 if (position == FixedPosition && !fixedFlowThreadContainer && (!ancestorLayer || ancestorLayer == renderer->view()->layer())) { 1355 // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling 1356 // localToAbsolute() on the RenderView. 1357 FloatPoint absPos = renderer->localToAbsolute(FloatPoint(), IsFixed); 1358 location += LayoutSize(absPos.x(), absPos.y()); 1359 return ancestorLayer; 1360 } 1361 1362 // For the fixed positioned elements inside a render flow thread, we should also skip the code path below 1363 // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed 1364 // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer. 1365 if (position == FixedPosition && !fixedFlowThreadContainer) { 1366 // For a fixed layers, we need to walk up to the root to see if there's a fixed position container 1367 // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform, 1368 // so we should always find the ancestor at or before we find the fixed position container. 1369 RenderLayer* fixedPositionContainerLayer = 0; 1370 bool foundAncestor = false; 1371 for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) { 1372 if (currLayer == ancestorLayer) 1373 foundAncestor = true; 1374 1375 if (isFixedPositionedContainer(currLayer)) { 1376 fixedPositionContainerLayer = currLayer; 1377 ASSERT_UNUSED(foundAncestor, foundAncestor); 1378 break; 1379 } 1380 } 1381 1382 ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least. 1383 1384 if (fixedPositionContainerLayer != ancestorLayer) { 1385 LayoutPoint fixedContainerCoords; 1386 layer->convertToLayerCoords(fixedPositionContainerLayer, fixedContainerCoords); 1387 1388 LayoutPoint ancestorCoords; 1389 ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorCoords); 1390 1391 location += (fixedContainerCoords - ancestorCoords); 1392 } else { 1393 location += toSize(layer->location()); 1394 } 1395 return ancestorLayer; 1396 } 1397 1398 RenderLayer* parentLayer; 1399 if (position == AbsolutePosition || position == FixedPosition) { 1400 // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way. 1401 parentLayer = layer->parent(); 1402 bool foundAncestorFirst = false; 1403 while (parentLayer) { 1404 // RenderFlowThread is a positioned container, child of RenderView, positioned at (0,0). 1405 // This implies that, for out-of-flow positioned elements inside a RenderFlowThread, 1406 // we are bailing out before reaching root layer. 1407 if (parentLayer->isPositionedContainer()) 1408 break; 1409 1410 if (parentLayer == ancestorLayer) { 1411 foundAncestorFirst = true; 1412 break; 1413 } 1414 1415 parentLayer = parentLayer->parent(); 1416 } 1417 1418 // We should not reach RenderView layer past the RenderFlowThread layer for any 1419 // children of the RenderFlowThread. 1420 ASSERT(!renderer->flowThreadContainingBlock() || parentLayer != renderer->view()->layer()); 1421 1422 if (foundAncestorFirst) { 1423 // Found ancestorLayer before the abs. positioned container, so compute offset of both relative 1424 // to enclosingPositionedAncestor and subtract. 1425 RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor(); 1426 1427 LayoutPoint thisCoords; 1428 layer->convertToLayerCoords(positionedAncestor, thisCoords); 1429 1430 LayoutPoint ancestorCoords; 1431 ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoords); 1432 1433 location += (thisCoords - ancestorCoords); 1434 return ancestorLayer; 1435 } 1436 } else 1437 parentLayer = layer->parent(); 1438 1439 if (!parentLayer) 1440 return 0; 1441 1442 location += toSize(layer->location()); 1443 return parentLayer; 1444 } 1445 1446 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const 1447 { 1448 if (ancestorLayer == this) 1449 return; 1450 1451 const RenderLayer* currLayer = this; 1452 while (currLayer && currLayer != ancestorLayer) 1453 currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, location); 1454 } 1455 1456 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect& rect) const 1457 { 1458 LayoutPoint delta; 1459 convertToLayerCoords(ancestorLayer, delta); 1460 rect.move(-delta.x(), -delta.y()); 1461 } 1462 1463 void RenderLayer::didUpdateNeedsCompositedScrolling() 1464 { 1465 updateSelfPaintingLayer(); 1466 } 1467 1468 void RenderLayer::updateReflectionInfo(const RenderStyle* oldStyle) 1469 { 1470 ASSERT(!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)); 1471 if (renderer()->hasReflection()) { 1472 if (!m_reflectionInfo) 1473 m_reflectionInfo = adoptPtrWillBeNoop(new RenderLayerReflectionInfo(*renderBox())); 1474 m_reflectionInfo->updateAfterStyleChange(oldStyle); 1475 } else if (m_reflectionInfo) { 1476 m_reflectionInfo->destroy(); 1477 m_reflectionInfo = nullptr; 1478 } 1479 } 1480 1481 void RenderLayer::updateStackingNode() 1482 { 1483 if (requiresStackingNode()) 1484 m_stackingNode = adoptPtr(new RenderLayerStackingNode(this)); 1485 else 1486 m_stackingNode = nullptr; 1487 } 1488 1489 void RenderLayer::updateScrollableArea() 1490 { 1491 if (requiresScrollableArea()) 1492 m_scrollableArea = adoptPtr(new RenderLayerScrollableArea(*this)); 1493 else 1494 m_scrollableArea = nullptr; 1495 } 1496 1497 bool RenderLayer::hasOverflowControls() const 1498 { 1499 return m_scrollableArea && (m_scrollableArea->hasScrollbar() || m_scrollableArea->hasScrollCorner() || renderer()->style()->resize() != RESIZE_NONE); 1500 } 1501 1502 void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, PaintLayerFlags paintFlags) 1503 { 1504 LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot); 1505 if (shouldPaintLayerInSoftwareMode(paintingInfo, paintFlags)) 1506 paintLayer(context, paintingInfo, paintFlags); 1507 } 1508 1509 void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot) 1510 { 1511 if (!m_containsDirtyOverlayScrollbars) 1512 return; 1513 1514 LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot); 1515 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); 1516 1517 m_containsDirtyOverlayScrollbars = false; 1518 } 1519 1520 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLayer) 1521 { 1522 if (startLayer == endLayer) 1523 return true; 1524 1525 RenderView* view = startLayer->renderer()->view(); 1526 for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock(); currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlock()) { 1527 if (currentBlock->layer() == endLayer) 1528 return true; 1529 } 1530 1531 return false; 1532 } 1533 1534 void RenderLayer::clipToRect(const LayerPaintingInfo& localPaintingInfo, GraphicsContext* context, const ClipRect& clipRect, 1535 PaintLayerFlags paintFlags, BorderRadiusClippingRule rule) 1536 { 1537 if (clipRect.rect() == localPaintingInfo.paintDirtyRect && !clipRect.hasRadius()) 1538 return; 1539 context->save(); 1540 context->clip(pixelSnappedIntRect(clipRect.rect())); 1541 1542 if (!clipRect.hasRadius()) 1543 return; 1544 1545 // If the clip rect has been tainted by a border radius, then we have to walk up our layer chain applying the clips from 1546 // any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our 1547 // containing block chain so we check that also. 1548 for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) { 1549 // Composited scrolling layers handle border-radius clip in the compositor via a mask layer. We do not 1550 // want to apply a border-radius clip to the layer contents itself, because that would require re-rastering 1551 // every frame to update the clip. We only want to make sure that the mask layer is properly clipped so 1552 // that it can in turn clip the scrolled contents in the compositor. 1553 if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase)) 1554 break; 1555 1556 if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(this, layer)) { 1557 LayoutPoint delta; 1558 layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta); 1559 context->clipRoundedRect(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size()))); 1560 } 1561 1562 if (layer == localPaintingInfo.rootLayer) 1563 break; 1564 } 1565 } 1566 1567 void RenderLayer::restoreClip(GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect) 1568 { 1569 if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius()) 1570 return; 1571 context->restore(); 1572 } 1573 1574 static inline bool shouldSuppressPaintingLayer(RenderLayer* layer) 1575 { 1576 // Avoid painting descendants of the root layer when stylesheets haven't loaded. This eliminates FOUC. 1577 // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document 1578 // will do a full paintInvalidationForWholeRenderer(). 1579 if (layer->renderer()->document().didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer()->isDocumentElement()) 1580 return true; 1581 1582 return false; 1583 } 1584 1585 static bool paintForFixedRootBackground(const RenderLayer* layer, PaintLayerFlags paintFlags) 1586 { 1587 return layer->renderer()->isDocumentElement() && (paintFlags & PaintLayerPaintingRootBackgroundOnly); 1588 } 1589 1590 static ShouldRespectOverflowClip shouldRespectOverflowClip(PaintLayerFlags paintFlags, const RenderObject* renderer) 1591 { 1592 return (paintFlags & PaintLayerPaintingOverflowContents || (paintFlags & PaintLayerPaintingChildClippingMaskPhase && renderer->hasClipPath())) ? IgnoreOverflowClip : RespectOverflowClip; 1593 } 1594 1595 void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 1596 { 1597 // https://code.google.com/p/chromium/issues/detail?id=343772 1598 DisableCompositingQueryAsserts disabler; 1599 1600 if (compositingState() != NotComposited) { 1601 if (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers) { 1602 // FIXME: ok, but what about PaintBehaviorFlattenCompositingLayers? That's for printing. 1603 // FIXME: why isn't the code here global, as opposed to being set on each paintLayer() call? 1604 paintFlags |= PaintLayerUncachedClipRects; 1605 } 1606 } 1607 1608 // Non self-painting leaf layers don't need to be painted as their renderer() should properly paint itself. 1609 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) 1610 return; 1611 1612 if (shouldSuppressPaintingLayer(this)) 1613 return; 1614 1615 // If this layer is totally invisible then there is nothing to paint. 1616 if (!renderer()->opacity()) 1617 return; 1618 1619 if (paintsWithTransparency(paintingInfo.paintBehavior)) 1620 paintFlags |= PaintLayerHaveTransparency; 1621 1622 // PaintLayerAppliedTransform is used in RenderReplica, to avoid applying the transform twice. 1623 if (paintsWithTransform(paintingInfo.paintBehavior) && !(paintFlags & PaintLayerAppliedTransform)) { 1624 TransformationMatrix layerTransform = renderableTransform(paintingInfo.paintBehavior); 1625 // If the transform can't be inverted, then don't paint anything. 1626 if (!layerTransform.isInvertible()) 1627 return; 1628 1629 // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency 1630 // layer from the parent now, assuming there is a parent 1631 if (paintFlags & PaintLayerHaveTransparency) { 1632 if (parent()) 1633 parent()->beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); 1634 else 1635 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); 1636 } 1637 1638 if (enclosingPaginationLayer()) { 1639 paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags); 1640 return; 1641 } 1642 1643 // Make sure the parent's clip rects have been calculated. 1644 ClipRect clipRect = paintingInfo.paintDirtyRect; 1645 if (parent()) { 1646 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize); 1647 if (shouldRespectOverflowClip(paintFlags, renderer()) == IgnoreOverflowClip) 1648 clipRectsContext.setIgnoreOverflowClip(); 1649 clipRect = clipper().backgroundClipRect(clipRectsContext); 1650 clipRect.intersect(paintingInfo.paintDirtyRect); 1651 1652 // Push the parent coordinate space's clip. 1653 parent()->clipToRect(paintingInfo, context, clipRect, paintFlags); 1654 } 1655 1656 paintLayerByApplyingTransform(context, paintingInfo, paintFlags); 1657 1658 // Restore the clip. 1659 if (parent()) 1660 parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect); 1661 1662 return; 1663 } 1664 1665 paintLayerContentsAndReflection(context, paintingInfo, paintFlags); 1666 } 1667 1668 void RenderLayer::paintLayerContentsAndReflection(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 1669 { 1670 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 1671 1672 PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform); 1673 1674 // Paint the reflection first if we have one. 1675 if (m_reflectionInfo) 1676 m_reflectionInfo->paint(context, paintingInfo, localPaintFlags | PaintLayerPaintingReflection); 1677 1678 localPaintFlags |= PaintLayerPaintingCompositingAllPhases; 1679 paintLayerContents(context, paintingInfo, localPaintFlags); 1680 } 1681 1682 void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 1683 { 1684 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 1685 ASSERT(!(paintFlags & PaintLayerAppliedTransform)); 1686 1687 bool haveTransparency = paintFlags & PaintLayerHaveTransparency; 1688 bool isSelfPaintingLayer = this->isSelfPaintingLayer(); 1689 bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars; 1690 bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositingScrollingPhase; 1691 bool isPaintingCompositedForeground = paintFlags & PaintLayerPaintingCompositingForegroundPhase; 1692 bool isPaintingCompositedBackground = paintFlags & PaintLayerPaintingCompositingBackgroundPhase; 1693 bool isPaintingOverflowContents = paintFlags & PaintLayerPaintingOverflowContents; 1694 // Outline always needs to be painted even if we have no visible content. Also, 1695 // the outline is painted in the background phase during composited scrolling. 1696 // If it were painted in the foreground phase, it would move with the scrolled 1697 // content. When not composited scrolling, the outline is painted in the 1698 // foreground phase. Since scrolled contents are moved by paint invalidation in this 1699 // case, the outline won't get 'dragged along'. 1700 bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars 1701 && ((isPaintingScrollingContent && isPaintingCompositedBackground) 1702 || (!isPaintingScrollingContent && isPaintingCompositedForeground)); 1703 bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars; 1704 1705 float deviceScaleFactor = blink::deviceScaleFactor(renderer()->frame()); 1706 context->setDeviceScaleFactor(deviceScaleFactor); 1707 1708 GraphicsContext* transparencyLayerContext = context; 1709 1710 if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isDocumentElement()) 1711 return; 1712 1713 // Ensure our lists are up-to-date. 1714 m_stackingNode->updateLayerListsIfNeeded(); 1715 1716 LayoutPoint offsetFromRoot; 1717 convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); 1718 1719 if (compositingState() == PaintsIntoOwnBacking) 1720 offsetFromRoot.move(subpixelAccumulation()); 1721 1722 LayoutRect rootRelativeBounds; 1723 bool rootRelativeBoundsComputed = false; 1724 1725 // Apply clip-path to context. 1726 GraphicsContextStateSaver clipStateSaver(*context, false); 1727 RenderStyle* style = renderer()->style(); 1728 RenderSVGResourceClipper* resourceClipper = 0; 1729 RenderSVGResourceClipper::ClipperState clipperState = RenderSVGResourceClipper::ClipperNotApplied; 1730 1731 // Clip-path, like border radius, must not be applied to the contents of a composited-scrolling container. 1732 // It must, however, still be applied to the mask layer, so that the compositor can properly mask the 1733 // scrolling contents and scrollbars. 1734 if (renderer()->hasClipPath() && style && (!needsCompositedScrolling() || paintFlags & PaintLayerPaintingChildClippingMaskPhase)) { 1735 ASSERT(style->clipPath()); 1736 if (style->clipPath()->type() == ClipPathOperation::SHAPE) { 1737 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->clipPath()); 1738 if (clipPath->isValid()) { 1739 clipStateSaver.save(); 1740 1741 if (!rootRelativeBoundsComputed) { 1742 rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); 1743 rootRelativeBoundsComputed = true; 1744 } 1745 1746 context->clipPath(clipPath->path(rootRelativeBounds), clipPath->windRule()); 1747 } 1748 } else if (style->clipPath()->type() == ClipPathOperation::REFERENCE) { 1749 ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClipPathOperation(style->clipPath()); 1750 Document& document = renderer()->document(); 1751 // FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405) 1752 Element* element = document.getElementById(referenceClipPathOperation->fragment()); 1753 if (isSVGClipPathElement(element) && element->renderer()) { 1754 // FIXME: Saving at this point is not required in the 'mask'- 1755 // case, or if the clip ends up empty. 1756 clipStateSaver.save(); 1757 if (!rootRelativeBoundsComputed) { 1758 rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); 1759 rootRelativeBoundsComputed = true; 1760 } 1761 1762 resourceClipper = toRenderSVGResourceClipper(toRenderSVGResourceContainer(element->renderer())); 1763 if (!resourceClipper->applyClippingToContext(renderer(), rootRelativeBounds, 1764 paintingInfo.paintDirtyRect, context, clipperState)) { 1765 // No need to post-apply the clipper if this failed. 1766 resourceClipper = 0; 1767 } 1768 } 1769 } 1770 } 1771 1772 // Blending operations must be performed only with the nearest ancestor stacking context. 1773 // Note that there is no need to create a transparency layer if we're painting the root. 1774 bool createTransparencyLayerForBlendMode = !renderer()->isDocumentElement() && m_stackingNode->isStackingContext() && hasDescendantWithBlendMode(); 1775 1776 if (createTransparencyLayerForBlendMode) 1777 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); 1778 1779 LayerPaintingInfo localPaintingInfo(paintingInfo); 1780 bool deferredFiltersEnabled = renderer()->document().settings()->deferredFiltersEnabled(); 1781 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters()); 1782 1783 LayerFragments layerFragments; 1784 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) { 1785 // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each 1786 // fragment should paint. 1787 collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect, 1788 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize, 1789 shouldRespectOverflowClip(paintFlags, renderer()), &offsetFromRoot, localPaintingInfo.subPixelAccumulation); 1790 updatePaintingInfoForFragments(layerFragments, localPaintingInfo, paintFlags, shouldPaintContent, &offsetFromRoot); 1791 } 1792 1793 if (filterPainter.haveFilterEffect()) { 1794 ASSERT(this->filterInfo()); 1795 1796 if (!rootRelativeBoundsComputed) 1797 rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); 1798 1799 if (filterPainter.prepareFilterEffect(this, rootRelativeBounds, paintingInfo.paintDirtyRect)) { 1800 1801 // Rewire the old context to a memory buffer, so that we can capture the contents of the layer. 1802 // NOTE: We saved the old context in the "transparencyLayerContext" local variable, to be able to start a transparency layer 1803 // on the original context and avoid duplicating "beginFilterEffect" after each transparency layer call. Also, note that 1804 // beginTransparencyLayers will only create a single lazy transparency layer, even though it is called twice in this method. 1805 // With deferred filters, we don't need a separate context, but we do need to do transparency and clipping before starting 1806 // filter processing. 1807 // FIXME: when the legacy path is removed, remove the transparencyLayerContext as well. 1808 ClipRect backgroundRect; 1809 if (deferredFiltersEnabled) { 1810 if (haveTransparency) { 1811 // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one after filter processing. 1812 beginTransparencyLayers(context, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior); 1813 } 1814 // We'll handle clipping to the dirty rect before filter rasterization. 1815 // Filter processing will automatically expand the clip rect and the offscreen to accommodate any filter outsets. 1816 // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved. 1817 backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect; 1818 clipToRect(localPaintingInfo, context, backgroundRect, paintFlags); 1819 // Subsequent code should not clip to the dirty rect, since we've already 1820 // done it above, and doing it later will defeat the outsets. 1821 localPaintingInfo.clipToDirtyRect = false; 1822 } 1823 context = filterPainter.beginFilterEffect(context); 1824 1825 if (!filterPainter.hasStartedFilterEffect() && deferredFiltersEnabled) { 1826 // If the the filter failed to start, undo the clip immediately 1827 restoreClip(context, localPaintingInfo.paintDirtyRect, backgroundRect); 1828 } 1829 1830 // Check that we didn't fail to allocate the graphics context for the offscreen buffer. 1831 if (filterPainter.hasStartedFilterEffect() && !deferredFiltersEnabled) { 1832 localPaintingInfo.paintDirtyRect = filterPainter.paintInvalidationRect(); 1833 // If the filter needs the full source image, we need to avoid using the clip rectangles. 1834 // Otherwise, if for example this layer has overflow:hidden, a drop shadow will not compute correctly. 1835 // Note that we will still apply the clipping on the final rendering of the filter. 1836 localPaintingInfo.clipToDirtyRect = !filterRenderer()->hasFilterThatMovesPixels(); 1837 } 1838 } 1839 } 1840 1841 if (filterPainter.hasStartedFilterEffect() && haveTransparency && !deferredFiltersEnabled) { 1842 // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one with the wrong context. 1843 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior); 1844 } 1845 1846 // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which 1847 // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set). 1848 // Else, our renderer tree may or may not contain the painting root, so we pass that root along 1849 // so it will be tested against as we descend through the renderers. 1850 RenderObject* paintingRootForRenderer = 0; 1851 if (localPaintingInfo.paintingRoot && !renderer()->isDescendantOf(localPaintingInfo.paintingRoot)) 1852 paintingRootForRenderer = localPaintingInfo.paintingRoot; 1853 1854 ASSERT(!(localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText)); 1855 bool selectionOnly = localPaintingInfo.paintBehavior & PaintBehaviorSelectionOnly; 1856 1857 bool shouldPaintBackground = isPaintingCompositedBackground && shouldPaintContent && !selectionOnly; 1858 bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground); 1859 bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPaintContent; 1860 bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForeground; 1861 bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars; 1862 bool shouldPaintMask = (paintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && renderer()->hasMask() && !selectionOnly; 1863 bool shouldPaintClippingMask = (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && shouldPaintContent && !selectionOnly; 1864 1865 PaintBehavior paintBehavior = PaintBehaviorNormal; 1866 if (paintFlags & PaintLayerPaintingSkipRootBackground) 1867 paintBehavior |= PaintBehaviorSkipRootBackground; 1868 else if (paintFlags & PaintLayerPaintingRootBackgroundOnly) 1869 paintBehavior |= PaintBehaviorRootBackgroundOnly; 1870 1871 if (shouldPaintBackground) { 1872 paintBackgroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency, 1873 localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags); 1874 } 1875 1876 if (shouldPaintNegZOrderList) 1877 paintChildren(NegativeZOrderChildren, context, paintingInfo, paintFlags); 1878 1879 if (shouldPaintOwnContents) { 1880 paintForegroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency, 1881 localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, paintFlags); 1882 } 1883 1884 if (shouldPaintOutline) 1885 paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags); 1886 1887 if (shouldPaintNormalFlowAndPosZOrderLists) 1888 paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, paintingInfo, paintFlags); 1889 1890 if (shouldPaintOverlayScrollbars) 1891 paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo, paintFlags); 1892 1893 if (filterPainter.hasStartedFilterEffect()) { 1894 // Apply the correct clipping (ie. overflow: hidden). 1895 // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved. 1896 ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect; 1897 if (!deferredFiltersEnabled) 1898 clipToRect(localPaintingInfo, transparencyLayerContext, backgroundRect, paintFlags); 1899 1900 context = filterPainter.applyFilterEffect(); 1901 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect); 1902 } 1903 1904 // Make sure that we now use the original transparency context. 1905 ASSERT(transparencyLayerContext == context); 1906 1907 if (shouldPaintMask) 1908 paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags); 1909 1910 if (shouldPaintClippingMask) { 1911 // Paint the border radius mask for the fragments. 1912 paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags); 1913 } 1914 1915 // End our transparency layer 1916 if ((haveTransparency || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency && !(m_reflectionInfo && m_reflectionInfo->isPaintingInsideReflection())) { 1917 context->endLayer(); 1918 context->restore(); 1919 m_usedTransparency = false; 1920 } 1921 1922 if (resourceClipper) 1923 resourceClipper->postApplyStatefulResource(renderer(), context, clipperState); 1924 } 1925 1926 void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& translationOffset) 1927 { 1928 // This involves subtracting out the position of the layer in our current coordinate space, but preserving 1929 // the accumulated error for sub-pixel layout. 1930 LayoutPoint delta; 1931 convertToLayerCoords(paintingInfo.rootLayer, delta); 1932 delta.moveBy(translationOffset); 1933 TransformationMatrix transform(renderableTransform(paintingInfo.paintBehavior)); 1934 IntPoint roundedDelta = roundedIntPoint(delta); 1935 transform.translateRight(roundedDelta.x(), roundedDelta.y()); 1936 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta); 1937 1938 // Apply the transform. 1939 GraphicsContextStateSaver stateSaver(*context, false); 1940 if (!transform.isIdentity()) { 1941 stateSaver.save(); 1942 context->concatCTM(transform.toAffineTransform()); 1943 } 1944 1945 // Now do a paint with the root layer shifted to be us. 1946 LayerPaintingInfo transformedPaintingInfo(this, enclosingIntRect(transform.inverse().mapRect(paintingInfo.paintDirtyRect)), paintingInfo.paintBehavior, 1947 adjustedSubPixelAccumulation, paintingInfo.paintingRoot); 1948 paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags); 1949 } 1950 1951 bool RenderLayer::shouldPaintLayerInSoftwareMode(const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 1952 { 1953 DisableCompositingQueryAsserts disabler; 1954 1955 return compositingState() == NotComposited 1956 || compositingState() == HasOwnBackingButPaintsIntoAncestor 1957 || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers) 1958 || ((paintFlags & PaintLayerPaintingReflection) && !has3DTransform()) 1959 || paintForFixedRootBackground(this, paintFlags); 1960 } 1961 1962 void RenderLayer::paintChildren(unsigned childrenToVisit, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 1963 { 1964 if (!hasSelfPaintingLayerDescendant()) 1965 return; 1966 1967 #if ENABLE(ASSERT) 1968 LayerListMutationDetector mutationChecker(m_stackingNode.get()); 1969 #endif 1970 1971 RenderLayerStackingNodeIterator iterator(*m_stackingNode, childrenToVisit); 1972 while (RenderLayerStackingNode* child = iterator.next()) { 1973 RenderLayer* childLayer = child->layer(); 1974 // If this RenderLayer should paint into its own backing or a grouped backing, that will be done via CompositedLayerMapping::paintContents() 1975 // and CompositedLayerMapping::doPaintTask(). 1976 if (!childLayer->shouldPaintLayerInSoftwareMode(paintingInfo, paintFlags)) 1977 continue; 1978 1979 if (!childLayer->isPaginated()) 1980 childLayer->paintLayer(context, paintingInfo, paintFlags); 1981 else 1982 paintPaginatedChildLayer(childLayer, context, paintingInfo, paintFlags); 1983 } 1984 } 1985 1986 void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, const LayoutRect& dirtyRect, 1987 ClipRectsCacheSlot clipRectsCacheSlot, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot, 1988 const LayoutSize& subPixelAccumulation, const LayoutRect* layerBoundingBox) 1989 { 1990 if (!enclosingPaginationLayer() || hasTransform()) { 1991 // For unpaginated layers, there is only one fragment. 1992 LayerFragment fragment; 1993 ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy, subPixelAccumulation); 1994 if (respectOverflowClip == IgnoreOverflowClip) 1995 clipRectsContext.setIgnoreOverflowClip(); 1996 clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot); 1997 fragments.append(fragment); 1998 return; 1999 } 2000 2001 // Compute our offset within the enclosing pagination layer. 2002 LayoutPoint offsetWithinPaginatedLayer; 2003 convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginatedLayer); 2004 2005 // Calculate clip rects relative to the enclosingPaginationLayer. The purpose of this call is to determine our bounds clipped to intermediate 2006 // layers between us and the pagination context. It's important to minimize the number of fragments we need to create and this helps with that. 2007 ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy); 2008 if (respectOverflowClip == IgnoreOverflowClip) 2009 paginationClipRectsContext.setIgnoreOverflowClip(); 2010 LayoutRect layerBoundsInFlowThread; 2011 ClipRect backgroundRectInFlowThread; 2012 ClipRect foregroundRectInFlowThread; 2013 ClipRect outlineRectInFlowThread; 2014 clipper().calculateRects(paginationClipRectsContext, PaintInfo::infiniteRect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, 2015 outlineRectInFlowThread, &offsetWithinPaginatedLayer); 2016 2017 // Take our bounding box within the flow thread and clip it. 2018 LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : physicalBoundingBox(enclosingPaginationLayer(), &offsetWithinPaginatedLayer); 2019 layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect()); 2020 2021 // Shift the dirty rect into flow thread coordinates. 2022 LayoutPoint offsetOfPaginationLayerFromRoot; 2023 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot); 2024 LayoutRect dirtyRectInFlowThread(dirtyRect); 2025 dirtyRectInFlowThread.moveBy(-offsetOfPaginationLayerFromRoot); 2026 2027 // Tell the flow thread to collect the fragments. We pass enough information to create a minimal number of fragments based off the pages/columns 2028 // that intersect the actual dirtyRect as well as the pages/columns that intersect our layer's bounding box. 2029 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer()); 2030 enclosingFlowThread->collectLayerFragments(fragments, layerBoundingBoxInFlowThread, dirtyRectInFlowThread); 2031 2032 if (fragments.isEmpty()) 2033 return; 2034 2035 // Get the parent clip rects of the pagination layer, since we need to intersect with that when painting column contents. 2036 ClipRect ancestorClipRect = dirtyRect; 2037 if (enclosingPaginationLayer()->parent()) { 2038 ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy); 2039 if (respectOverflowClip == IgnoreOverflowClip) 2040 clipRectsContext.setIgnoreOverflowClip(); 2041 ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipRect(clipRectsContext); 2042 ancestorClipRect.intersect(dirtyRect); 2043 } 2044 2045 for (size_t i = 0; i < fragments.size(); ++i) { 2046 LayerFragment& fragment = fragments.at(i); 2047 2048 // Set our four rects with all clipping applied that was internal to the flow thread. 2049 fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, outlineRectInFlowThread); 2050 2051 // Shift to the root-relative physical position used when painting the flow thread in this fragment. 2052 fragment.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot); 2053 2054 // Intersect the fragment with our ancestor's background clip so that e.g., columns in an overflow:hidden block are 2055 // properly clipped by the overflow. 2056 fragment.intersect(ancestorClipRect.rect()); 2057 2058 // Now intersect with our pagination clip. This will typically mean we're just intersecting the dirty rect with the column 2059 // clip, so the column clip ends up being all we apply. 2060 fragment.intersect(fragment.paginationClip); 2061 } 2062 } 2063 2064 void RenderLayer::updatePaintingInfoForFragments(LayerFragments& fragments, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags localPaintFlags, 2065 bool shouldPaintContent, const LayoutPoint* offsetFromRoot) 2066 { 2067 ASSERT(offsetFromRoot); 2068 for (size_t i = 0; i < fragments.size(); ++i) { 2069 LayerFragment& fragment = fragments.at(i); 2070 fragment.shouldPaintContent = shouldPaintContent; 2071 if (this != localPaintingInfo.rootLayer || !(localPaintFlags & PaintLayerPaintingOverflowContents)) { 2072 LayoutPoint newOffsetFromRoot = *offsetFromRoot + fragment.paginationOffset; 2073 fragment.shouldPaintContent &= intersectsDamageRect(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLayer, &newOffsetFromRoot); 2074 } 2075 } 2076 } 2077 2078 void RenderLayer::paintTransformedLayerIntoFragments(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 2079 { 2080 LayerFragments enclosingPaginationFragments; 2081 LayoutPoint offsetOfPaginationLayerFromRoot; 2082 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); 2083 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, 2084 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize, 2085 shouldRespectOverflowClip(paintFlags, renderer()), &offsetOfPaginationLayerFromRoot, paintingInfo.subPixelAccumulation, &transformedExtent); 2086 2087 for (size_t i = 0; i < enclosingPaginationFragments.size(); ++i) { 2088 const LayerFragment& fragment = enclosingPaginationFragments.at(i); 2089 2090 // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and 2091 // the enclosing pagination layer. 2092 LayoutRect clipRect = fragment.backgroundRect.rect(); 2093 2094 // Now compute the clips within a given fragment 2095 if (parent() != enclosingPaginationLayer()) { 2096 enclosingPaginationLayer()->convertToLayerCoords(paintingInfo.rootLayer, offsetOfPaginationLayerFromRoot); 2097 2098 ClipRectsContext clipRectsContext(enclosingPaginationLayer(), (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize); 2099 if (shouldRespectOverflowClip(paintFlags, renderer()) == IgnoreOverflowClip) 2100 clipRectsContext.setIgnoreOverflowClip(); 2101 LayoutRect parentClipRect = clipper().backgroundClipRect(clipRectsContext).rect(); 2102 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot); 2103 clipRect.intersect(parentClipRect); 2104 } 2105 2106 parent()->clipToRect(paintingInfo, context, clipRect, paintFlags); 2107 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset); 2108 parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect); 2109 } 2110 } 2111 2112 static inline LayoutSize subPixelAccumulationIfNeeded(const LayoutSize& subPixelAccumulation, CompositingState compositingState) 2113 { 2114 // Only apply the sub-pixel accumulation if we don't paint into our own backing layer, otherwise the position 2115 // of the renderer already includes any sub-pixel offset. 2116 if (compositingState == PaintsIntoOwnBacking) 2117 return LayoutSize(); 2118 return subPixelAccumulation; 2119 } 2120 2121 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext, 2122 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 2123 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) 2124 { 2125 for (size_t i = 0; i < layerFragments.size(); ++i) { 2126 const LayerFragment& fragment = layerFragments.at(i); 2127 if (!fragment.shouldPaintContent) 2128 continue; 2129 2130 // Begin transparency layers lazily now that we know we have to paint something. 2131 if (haveTransparency || paintsWithBlendMode()) 2132 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior); 2133 2134 if (localPaintingInfo.clipToDirtyRect) { 2135 // Paint our background first, before painting any child layers. 2136 // Establish the clip used to paint our background. 2137 clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self. 2138 } 2139 2140 // Paint the background. 2141 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info. 2142 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer()); 2143 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))); 2144 2145 if (localPaintingInfo.clipToDirtyRect) 2146 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect); 2147 } 2148 } 2149 2150 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext, 2151 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 2152 RenderObject* paintingRootForRenderer, bool selectionOnly, PaintLayerFlags paintFlags) 2153 { 2154 // Begin transparency if we have something to paint. 2155 if (haveTransparency || paintsWithBlendMode()) { 2156 for (size_t i = 0; i < layerFragments.size(); ++i) { 2157 const LayerFragment& fragment = layerFragments.at(i); 2158 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty()) { 2159 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior); 2160 break; 2161 } 2162 } 2163 } 2164 2165 // Optimize clipping for the single fragment case. 2166 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty(); 2167 if (shouldClip) 2168 clipToRect(localPaintingInfo, context, layerFragments[0].foregroundRect, paintFlags); 2169 2170 // We have to loop through every fragment multiple times, since we have to issue paint invalidations in each specific phase in order for 2171 // interleaving of the fragments to work properly. 2172 paintForegroundForFragmentsWithPhase(selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds, layerFragments, 2173 context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags); 2174 2175 if (!selectionOnly) { 2176 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags); 2177 paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags); 2178 paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags); 2179 } 2180 2181 if (shouldClip) 2182 restoreClip(context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect); 2183 } 2184 2185 void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const LayerFragments& layerFragments, GraphicsContext* context, 2186 const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) 2187 { 2188 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() > 1; 2189 2190 for (size_t i = 0; i < layerFragments.size(); ++i) { 2191 const LayerFragment& fragment = layerFragments.at(i); 2192 if (!fragment.shouldPaintContent || fragment.foregroundRect.isEmpty()) 2193 continue; 2194 2195 if (shouldClip) 2196 clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags); 2197 2198 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer()); 2199 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))); 2200 2201 if (shouldClip) 2202 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect); 2203 } 2204 } 2205 2206 void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo, 2207 PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) 2208 { 2209 for (size_t i = 0; i < layerFragments.size(); ++i) { 2210 const LayerFragment& fragment = layerFragments.at(i); 2211 if (fragment.outlineRect.isEmpty()) 2212 continue; 2213 2214 // Paint our own outline 2215 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer()); 2216 clipToRect(localPaintingInfo, context, fragment.outlineRect, paintFlags, DoNotIncludeSelfForBorderRadius); 2217 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))); 2218 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.outlineRect); 2219 } 2220 } 2221 2222 void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo, 2223 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) 2224 { 2225 for (size_t i = 0; i < layerFragments.size(); ++i) { 2226 const LayerFragment& fragment = layerFragments.at(i); 2227 if (!fragment.shouldPaintContent) 2228 continue; 2229 2230 if (localPaintingInfo.clipToDirtyRect) 2231 clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self. 2232 2233 // Paint the mask. 2234 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info. 2235 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer()); 2236 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))); 2237 2238 if (localPaintingInfo.clipToDirtyRect) 2239 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect); 2240 } 2241 } 2242 2243 void RenderLayer::paintChildClippingMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo, 2244 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) 2245 { 2246 for (size_t i = 0; i < layerFragments.size(); ++i) { 2247 const LayerFragment& fragment = layerFragments.at(i); 2248 if (!fragment.shouldPaintContent) 2249 continue; 2250 2251 if (localPaintingInfo.clipToDirtyRect) 2252 clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self. 2253 2254 // Paint the the clipped mask. 2255 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseClippingMask, PaintBehaviorNormal, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer()); 2256 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))); 2257 2258 if (localPaintingInfo.clipToDirtyRect) 2259 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect); 2260 } 2261 } 2262 2263 void RenderLayer::paintOverflowControlsForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags) 2264 { 2265 for (size_t i = 0; i < layerFragments.size(); ++i) { 2266 const LayerFragment& fragment = layerFragments.at(i); 2267 clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags); 2268 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea()) 2269 scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true); 2270 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect); 2271 } 2272 } 2273 2274 void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 2275 { 2276 // We need to do multiple passes, breaking up our child layer into strips. 2277 Vector<RenderLayer*> columnLayers; 2278 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode(); 2279 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) { 2280 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox())) 2281 columnLayers.append(curr); 2282 if (curr->stackingNode() == ancestorNode) 2283 break; 2284 } 2285 2286 // It is possible for paintLayer() to be called after the child layer ceases to be paginated but before 2287 // updatePaginationRecusive() is called and resets the isPaginated() flag, see <rdar://problem/10098679>. 2288 // If this is the case, just bail out, since the upcoming call to updatePaginationRecusive() will paint invalidate the layer. 2289 // FIXME: Is this true anymore? This seems very suspicious. 2290 if (!columnLayers.size()) 2291 return; 2292 2293 paintChildLayerIntoColumns(childLayer, context, paintingInfo, paintFlags, columnLayers, columnLayers.size() - 1); 2294 } 2295 2296 void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, 2297 PaintLayerFlags paintFlags, const Vector<RenderLayer*>& columnLayers, size_t colIndex) 2298 { 2299 RenderBlock* columnBlock = toRenderBlock(columnLayers[colIndex]->renderer()); 2300 2301 ASSERT(columnBlock && columnBlock->hasColumns()); 2302 if (!columnBlock || !columnBlock->hasColumns()) 2303 return; 2304 2305 LayoutPoint layerOffset; 2306 // FIXME: It looks suspicious to call convertToLayerCoords here 2307 // as canUseConvertToLayerCoords is true for this layer. 2308 columnBlock->layer()->convertToLayerCoords(paintingInfo.rootLayer, layerOffset); 2309 2310 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode(); 2311 2312 ColumnInfo* colInfo = columnBlock->columnInfo(); 2313 unsigned colCount = columnBlock->columnCount(colInfo); 2314 LayoutUnit currLogicalTopOffset = 0; 2315 for (unsigned i = 0; i < colCount; i++) { 2316 // For each rect, we clip to the rect, and then we adjust our coords. 2317 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i); 2318 columnBlock->flipForWritingMode(colRect); 2319 LayoutUnit logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent(); 2320 LayoutSize offset; 2321 if (isHorizontal) { 2322 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) 2323 offset = LayoutSize(logicalLeftOffset, currLogicalTopOffset); 2324 else 2325 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop()); 2326 } else { 2327 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) 2328 offset = LayoutSize(currLogicalTopOffset, logicalLeftOffset); 2329 else 2330 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0); 2331 } 2332 2333 colRect.moveBy(layerOffset); 2334 2335 LayoutRect localDirtyRect(paintingInfo.paintDirtyRect); 2336 localDirtyRect.intersect(colRect); 2337 2338 if (!localDirtyRect.isEmpty()) { 2339 GraphicsContextStateSaver stateSaver(*context); 2340 2341 // Each strip pushes a clip, since column boxes are specified as being 2342 // like overflow:hidden. 2343 context->clip(enclosingIntRect(colRect)); 2344 2345 if (!colIndex) { 2346 // Apply a translation transform to change where the layer paints. 2347 TransformationMatrix oldTransform; 2348 bool oldHasTransform = childLayer->transform(); 2349 if (oldHasTransform) 2350 oldTransform = *childLayer->transform(); 2351 TransformationMatrix newTransform(oldTransform); 2352 newTransform.translateRight(roundToInt(offset.width()), roundToInt(offset.height())); 2353 2354 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform)); 2355 2356 LayerPaintingInfo localPaintingInfo(paintingInfo); 2357 localPaintingInfo.paintDirtyRect = localDirtyRect; 2358 childLayer->paintLayer(context, localPaintingInfo, paintFlags); 2359 2360 if (oldHasTransform) 2361 childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform)); 2362 else 2363 childLayer->m_transform.clear(); 2364 } else { 2365 // Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space. 2366 // This involves subtracting out the position of the layer in our current coordinate space. 2367 LayoutPoint childOffset; 2368 columnLayers[colIndex - 1]->convertToLayerCoords(paintingInfo.rootLayer, childOffset); 2369 TransformationMatrix transform; 2370 transform.translateRight(roundToInt(childOffset.x() + offset.width()), roundToInt(childOffset.y() + offset.height())); 2371 2372 // Apply the transform. 2373 context->concatCTM(transform.toAffineTransform()); 2374 2375 // Now do a paint with the root layer shifted to be the next multicol block. 2376 LayerPaintingInfo columnPaintingInfo(paintingInfo); 2377 columnPaintingInfo.rootLayer = columnLayers[colIndex - 1]; 2378 columnPaintingInfo.paintDirtyRect = transform.inverse().mapRect(localDirtyRect); 2379 paintChildLayerIntoColumns(childLayer, context, columnPaintingInfo, paintFlags, columnLayers, colIndex - 1); 2380 } 2381 } 2382 2383 // Move to the next position. 2384 LayoutUnit blockDelta = isHorizontal ? colRect.height() : colRect.width(); 2385 if (columnBlock->style()->isFlippedBlocksWritingMode()) 2386 currLogicalTopOffset += blockDelta; 2387 else 2388 currLogicalTopOffset -= blockDelta; 2389 } 2390 } 2391 2392 static inline LayoutRect frameVisibleRect(RenderObject* renderer) 2393 { 2394 FrameView* frameView = renderer->document().view(); 2395 if (!frameView) 2396 return LayoutRect(); 2397 2398 return frameView->visibleContentRect(); 2399 } 2400 2401 bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result) 2402 { 2403 return hitTest(request, result.hitTestLocation(), result); 2404 } 2405 2406 bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation& hitTestLocation, HitTestResult& result) 2407 { 2408 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 2409 2410 // RenderView should make sure to update layout before entering hit testing 2411 ASSERT(!renderer()->frame()->view()->layoutPending()); 2412 ASSERT(!renderer()->document().renderView()->needsLayout()); 2413 2414 LayoutRect hitTestArea = renderer()->view()->documentRect(); 2415 if (!request.ignoreClipping()) 2416 hitTestArea.intersect(frameVisibleRect(renderer())); 2417 2418 RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestArea, hitTestLocation, false); 2419 if (!insideLayer) { 2420 // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down, 2421 // return ourselves. We do this so mouse events continue getting delivered after a drag has 2422 // exited the WebView, and so hit testing over a scrollbar hits the content document. 2423 // In addtion, it is possible for the mouse to stay in the document but there is no element. 2424 // At that time, the events of the mouse should be fired. 2425 LayoutPoint hitPoint = hitTestLocation.point(); 2426 if (!request.isChildFrameHitTest() && ((request.active() || request.release()) || (request.move() && hitTestArea.contains(hitPoint.x(), hitPoint.y()))) && isRootLayer()) { 2427 renderer()->updateHitTestResult(result, toRenderView(renderer())->flipForWritingMode(hitTestLocation.point())); 2428 insideLayer = this; 2429 } 2430 } 2431 2432 // Now determine if the result is inside an anchor - if the urlElement isn't already set. 2433 Node* node = result.innerNode(); 2434 if (node && !result.URLElement()) 2435 result.setURLElement(node->enclosingLinkEventParentOrSelf()); 2436 2437 // Now return whether we were inside this layer (this will always be true for the root 2438 // layer). 2439 return insideLayer; 2440 } 2441 2442 Node* RenderLayer::enclosingElement() const 2443 { 2444 for (RenderObject* r = renderer(); r; r = r->parent()) { 2445 if (Node* e = r->node()) 2446 return e; 2447 } 2448 ASSERT_NOT_REACHED(); 2449 return 0; 2450 } 2451 2452 bool RenderLayer::isInTopLayer() const 2453 { 2454 Node* node = renderer()->node(); 2455 return node && node->isElementNode() && toElement(node)->isInTopLayer(); 2456 } 2457 2458 // Compute the z-offset of the point in the transformState. 2459 // This is effectively projecting a ray normal to the plane of ancestor, finding where that 2460 // ray intersects target, and computing the z delta between those two points. 2461 static double computeZOffset(const HitTestingTransformState& transformState) 2462 { 2463 // We got an affine transform, so no z-offset 2464 if (transformState.m_accumulatedTransform.isAffine()) 2465 return 0; 2466 2467 // Flatten the point into the target plane 2468 FloatPoint targetPoint = transformState.mappedPoint(); 2469 2470 // Now map the point back through the transform, which computes Z. 2471 FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint)); 2472 return backmappedPoint.z(); 2473 } 2474 2475 PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer, 2476 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, 2477 const HitTestingTransformState* containerTransformState, 2478 const LayoutPoint& translationOffset) const 2479 { 2480 RefPtr<HitTestingTransformState> transformState; 2481 LayoutPoint offset; 2482 if (containerTransformState) { 2483 // If we're already computing transform state, then it's relative to the container (which we know is non-null). 2484 transformState = HitTestingTransformState::create(*containerTransformState); 2485 convertToLayerCoords(containerLayer, offset); 2486 } else { 2487 // If this is the first time we need to make transform state, then base it off of hitTestLocation, 2488 // which is relative to rootLayer. 2489 transformState = HitTestingTransformState::create(hitTestLocation.transformedPoint(), hitTestLocation.transformedRect(), FloatQuad(hitTestRect)); 2490 convertToLayerCoords(rootLayer, offset); 2491 } 2492 offset.moveBy(translationOffset); 2493 2494 RenderObject* containerRenderer = containerLayer ? containerLayer->renderer() : 0; 2495 if (renderer()->shouldUseTransformFromContainer(containerRenderer)) { 2496 TransformationMatrix containerTransform; 2497 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(offset), containerTransform); 2498 transformState->applyTransform(containerTransform, HitTestingTransformState::AccumulateTransform); 2499 } else { 2500 transformState->translate(offset.x(), offset.y(), HitTestingTransformState::AccumulateTransform); 2501 } 2502 2503 return transformState; 2504 } 2505 2506 2507 static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, double* zOffset, const HitTestingTransformState* transformState) 2508 { 2509 if (!hitLayer) 2510 return false; 2511 2512 // The hit layer is depth-sorting with other layers, so just say that it was hit. 2513 if (canDepthSort) 2514 return true; 2515 2516 // We need to look at z-depth to decide if this layer was hit. 2517 if (zOffset) { 2518 ASSERT(transformState); 2519 // This is actually computing our z, but that's OK because the hitLayer is coplanar with us. 2520 double childZOffset = computeZOffset(*transformState); 2521 if (childZOffset > *zOffset) { 2522 *zOffset = childZOffset; 2523 return true; 2524 } 2525 return false; 2526 } 2527 2528 return true; 2529 } 2530 2531 // hitTestLocation and hitTestRect are relative to rootLayer. 2532 // A 'flattening' layer is one preserves3D() == false. 2533 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer. 2534 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the containing flattening layer. 2535 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer. 2536 // 2537 // If zOffset is non-null (which indicates that the caller wants z offset information), 2538 // *zOffset on return is the z offset of the hit point relative to the containing flattening layer. 2539 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result, 2540 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, bool appliedTransform, 2541 const HitTestingTransformState* transformState, double* zOffset) 2542 { 2543 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) 2544 return 0; 2545 2546 // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate. 2547 2548 // Apply a transform if we have one. 2549 if (transform() && !appliedTransform) { 2550 if (enclosingPaginationLayer()) 2551 return hitTestTransformedLayerInFragments(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset); 2552 2553 // Make sure the parent's clip rects have been calculated. 2554 if (parent()) { 2555 ClipRect clipRect = clipper().backgroundClipRect(ClipRectsContext(rootLayer, RootRelativeClipRects, IncludeOverlayScrollbarSize)); 2556 // Go ahead and test the enclosing clip now. 2557 if (!clipRect.intersects(hitTestLocation)) 2558 return 0; 2559 } 2560 2561 return hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset); 2562 } 2563 2564 // Ensure our lists and 3d status are up-to-date. 2565 m_stackingNode->updateLayerListsIfNeeded(); 2566 update3DTransformedDescendantStatus(); 2567 2568 RefPtr<HitTestingTransformState> localTransformState; 2569 if (appliedTransform) { 2570 // We computed the correct state in the caller (above code), so just reference it. 2571 ASSERT(transformState); 2572 localTransformState = const_cast<HitTestingTransformState*>(transformState); 2573 } else if (transformState || m_has3DTransformedDescendant || preserves3D()) { 2574 // We need transform state for the first time, or to offset the container state, so create it here. 2575 localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState); 2576 } 2577 2578 // Check for hit test on backface if backface-visibility is 'hidden' 2579 if (localTransformState && renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) { 2580 TransformationMatrix invertedMatrix = localTransformState->m_accumulatedTransform.inverse(); 2581 // If the z-vector of the matrix is negative, the back is facing towards the viewer. 2582 if (invertedMatrix.m33() < 0) 2583 return 0; 2584 } 2585 2586 RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformState; 2587 if (localTransformState && !preserves3D()) { 2588 // Keep a copy of the pre-flattening state, for computing z-offsets for the container 2589 unflattenedTransformState = HitTestingTransformState::create(*localTransformState); 2590 // This layer is flattening, so flatten the state passed to descendants. 2591 localTransformState->flatten(); 2592 } 2593 2594 // The following are used for keeping track of the z-depth of the hit point of 3d-transformed 2595 // descendants. 2596 double localZOffset = -std::numeric_limits<double>::infinity(); 2597 double* zOffsetForDescendantsPtr = 0; 2598 double* zOffsetForContentsPtr = 0; 2599 2600 bool depthSortDescendants = false; 2601 if (preserves3D()) { 2602 depthSortDescendants = true; 2603 // Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down. 2604 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset; 2605 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset; 2606 } else if (zOffset) { 2607 zOffsetForDescendantsPtr = 0; 2608 // Container needs us to give back a z offset for the hit layer. 2609 zOffsetForContentsPtr = zOffset; 2610 } 2611 2612 // This variable tracks which layer the mouse ends up being inside. 2613 RenderLayer* candidateLayer = 0; 2614 2615 // Begin by walking our list of positive layers from highest z-index down to the lowest z-index. 2616 RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation, 2617 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); 2618 if (hitLayer) { 2619 if (!depthSortDescendants) 2620 return hitLayer; 2621 candidateLayer = hitLayer; 2622 } 2623 2624 // Now check our overflow objects. 2625 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, hitTestRect, hitTestLocation, 2626 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); 2627 if (hitLayer) { 2628 if (!depthSortDescendants) 2629 return hitLayer; 2630 candidateLayer = hitLayer; 2631 } 2632 2633 // Collect the fragments. This will compute the clip rectangles for each layer fragment. 2634 LayerFragments layerFragments; 2635 collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeClipRects, IncludeOverlayScrollbarSize); 2636 2637 if (m_scrollableArea && m_scrollableArea->hitTestResizerInFragments(layerFragments, hitTestLocation)) { 2638 renderer()->updateHitTestResult(result, hitTestLocation.point()); 2639 return this; 2640 } 2641 2642 // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. Check 2643 // every fragment in reverse order. 2644 if (isSelfPaintingLayer()) { 2645 // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost. 2646 HitTestResult tempResult(result.hitTestLocation()); 2647 bool insideFragmentForegroundRect = false; 2648 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestDescendants, insideFragmentForegroundRect) 2649 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) { 2650 if (result.isRectBasedTest()) 2651 result.append(tempResult); 2652 else 2653 result = tempResult; 2654 if (!depthSortDescendants) 2655 return this; 2656 // Foreground can depth-sort with descendant layers, so keep this as a candidate. 2657 candidateLayer = this; 2658 } else if (insideFragmentForegroundRect && result.isRectBasedTest()) 2659 result.append(tempResult); 2660 } 2661 2662 // Now check our negative z-index children. 2663 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation, 2664 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); 2665 if (hitLayer) { 2666 if (!depthSortDescendants) 2667 return hitLayer; 2668 candidateLayer = hitLayer; 2669 } 2670 2671 // If we found a layer, return. Child layers, and foreground always render in front of background. 2672 if (candidateLayer) 2673 return candidateLayer; 2674 2675 if (isSelfPaintingLayer()) { 2676 HitTestResult tempResult(result.hitTestLocation()); 2677 bool insideFragmentBackgroundRect = false; 2678 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestSelf, insideFragmentBackgroundRect) 2679 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) { 2680 if (result.isRectBasedTest()) 2681 result.append(tempResult); 2682 else 2683 result = tempResult; 2684 return this; 2685 } 2686 if (insideFragmentBackgroundRect && result.isRectBasedTest()) 2687 result.append(tempResult); 2688 } 2689 2690 return 0; 2691 } 2692 2693 bool RenderLayer::hitTestContentsForFragments(const LayerFragments& layerFragments, const HitTestRequest& request, HitTestResult& result, 2694 const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& insideClipRect) const 2695 { 2696 if (layerFragments.isEmpty()) 2697 return false; 2698 2699 for (int i = layerFragments.size() - 1; i >= 0; --i) { 2700 const LayerFragment& fragment = layerFragments.at(i); 2701 if ((hitTestFilter == HitTestSelf && !fragment.backgroundRect.intersects(hitTestLocation)) 2702 || (hitTestFilter == HitTestDescendants && !fragment.foregroundRect.intersects(hitTestLocation))) 2703 continue; 2704 insideClipRect = true; 2705 if (hitTestContents(request, result, fragment.layerBounds, hitTestLocation, hitTestFilter)) 2706 return true; 2707 } 2708 2709 return false; 2710 } 2711 2712 RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result, 2713 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset) 2714 { 2715 LayerFragments enclosingPaginationFragments; 2716 LayoutPoint offsetOfPaginationLayerFromRoot; 2717 // FIXME: We're missing a sub-pixel offset here crbug.com/348728 2718 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox, LayoutSize()); 2719 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestRect, 2720 RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent); 2721 2722 for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) { 2723 const LayerFragment& fragment = enclosingPaginationFragments.at(i); 2724 2725 // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and 2726 // the enclosing pagination layer. 2727 LayoutRect clipRect = fragment.backgroundRect.rect(); 2728 2729 // Now compute the clips within a given fragment 2730 if (parent() != enclosingPaginationLayer()) { 2731 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot); 2732 LayoutRect parentClipRect = clipper().backgroundClipRect(ClipRectsContext(enclosingPaginationLayer(), RootRelativeClipRects, IncludeOverlayScrollbarSize)).rect(); 2733 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot); 2734 clipRect.intersect(parentClipRect); 2735 } 2736 2737 if (!hitTestLocation.intersects(clipRect)) 2738 continue; 2739 2740 RenderLayer* hitLayer = hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, 2741 transformState, zOffset, fragment.paginationOffset); 2742 if (hitLayer) 2743 return hitLayer; 2744 } 2745 2746 return 0; 2747 } 2748 2749 RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result, 2750 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset, 2751 const LayoutPoint& translationOffset) 2752 { 2753 // Create a transform state to accumulate this transform. 2754 RefPtr<HitTestingTransformState> newTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, translationOffset); 2755 2756 // If the transform can't be inverted, then don't hit test this layer at all. 2757 if (!newTransformState->m_accumulatedTransform.isInvertible()) 2758 return 0; 2759 2760 // Compute the point and the hit test rect in the coords of this layer by using the values 2761 // from the transformState, which store the point and quad in the coords of the last flattened 2762 // layer, and the accumulated transform which lets up map through preserve-3d layers. 2763 // 2764 // We can't just map hitTestLocation and hitTestRect because they may have been flattened (losing z) 2765 // by our container. 2766 FloatPoint localPoint = newTransformState->mappedPoint(); 2767 FloatQuad localPointQuad = newTransformState->mappedQuad(); 2768 LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea(); 2769 HitTestLocation newHitTestLocation; 2770 if (hitTestLocation.isRectBasedTest()) 2771 newHitTestLocation = HitTestLocation(localPoint, localPointQuad); 2772 else 2773 newHitTestLocation = HitTestLocation(localPoint); 2774 2775 // Now do a hit test with the root layer shifted to be us. 2776 return hitTestLayer(this, containerLayer, request, result, localHitTestRect, newHitTestLocation, true, newTransformState.get(), zOffset); 2777 } 2778 2779 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter) const 2780 { 2781 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 2782 2783 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(layerBounds.location() - renderBoxLocation()), hitTestFilter)) { 2784 // It's wrong to set innerNode, but then claim that you didn't hit anything, unless it is 2785 // a rect-based test. 2786 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBasedTestResult().size())); 2787 return false; 2788 } 2789 2790 // For positioned generated content, we might still not have a 2791 // node by the time we get to the layer level, since none of 2792 // the content in the layer has an element. So just walk up 2793 // the tree. 2794 if (!result.innerNode() || !result.innerNonSharedNode()) { 2795 Node* e = enclosingElement(); 2796 if (!result.innerNode()) 2797 result.setInnerNode(e); 2798 if (!result.innerNonSharedNode()) 2799 result.setInnerNonSharedNode(e); 2800 } 2801 2802 return true; 2803 } 2804 2805 RenderLayer* RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, RenderLayer* rootLayer, 2806 const HitTestRequest& request, HitTestResult& result, 2807 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, 2808 const HitTestingTransformState* transformState, 2809 double* zOffsetForDescendants, double* zOffset, 2810 const HitTestingTransformState* unflattenedTransformState, 2811 bool depthSortDescendants) 2812 { 2813 if (!hasSelfPaintingLayerDescendant()) 2814 return 0; 2815 2816 RenderLayer* resultLayer = 0; 2817 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoVisit); 2818 while (RenderLayerStackingNode* child = iterator.next()) { 2819 RenderLayer* childLayer = child->layer(); 2820 RenderLayer* hitLayer = 0; 2821 HitTestResult tempResult(result.hitTestLocation()); 2822 if (childLayer->isPaginated()) 2823 hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request, tempResult, hitTestRect, hitTestLocation, transformState, zOffsetForDescendants); 2824 else 2825 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants); 2826 2827 // If it a rect-based test, we can safely append the temporary result since it might had hit 2828 // nodes but not necesserily had hitLayer set. 2829 if (result.isRectBasedTest()) 2830 result.append(tempResult); 2831 2832 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) { 2833 resultLayer = hitLayer; 2834 if (!result.isRectBasedTest()) 2835 result = tempResult; 2836 if (!depthSortDescendants) 2837 break; 2838 } 2839 } 2840 2841 return resultLayer; 2842 } 2843 2844 RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result, 2845 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset) 2846 { 2847 Vector<RenderLayer*> columnLayers; 2848 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode(); 2849 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) { 2850 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox())) 2851 columnLayers.append(curr); 2852 if (curr->stackingNode() == ancestorNode) 2853 break; 2854 } 2855 2856 ASSERT(columnLayers.size()); 2857 return hitTestChildLayerColumns(childLayer, rootLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset, 2858 columnLayers, columnLayers.size() - 1); 2859 } 2860 2861 RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result, 2862 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset, 2863 const Vector<RenderLayer*>& columnLayers, size_t columnIndex) 2864 { 2865 RenderBlock* columnBlock = toRenderBlock(columnLayers[columnIndex]->renderer()); 2866 2867 ASSERT(columnBlock && columnBlock->hasColumns()); 2868 if (!columnBlock || !columnBlock->hasColumns()) 2869 return 0; 2870 2871 LayoutPoint layerOffset; 2872 columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset); 2873 2874 ColumnInfo* colInfo = columnBlock->columnInfo(); 2875 int colCount = columnBlock->columnCount(colInfo); 2876 2877 // We have to go backwards from the last column to the first. 2878 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode(); 2879 LayoutUnit logicalLeft = columnBlock->logicalLeftOffsetForContent(); 2880 LayoutUnit currLogicalTopOffset = 0; 2881 int i; 2882 for (i = 0; i < colCount; i++) { 2883 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i); 2884 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width()); 2885 if (columnBlock->style()->isFlippedBlocksWritingMode()) 2886 currLogicalTopOffset += blockDelta; 2887 else 2888 currLogicalTopOffset -= blockDelta; 2889 } 2890 for (i = colCount - 1; i >= 0; i--) { 2891 // For each rect, we clip to the rect, and then we adjust our coords. 2892 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i); 2893 columnBlock->flipForWritingMode(colRect); 2894 LayoutUnit currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft; 2895 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width()); 2896 if (columnBlock->style()->isFlippedBlocksWritingMode()) 2897 currLogicalTopOffset -= blockDelta; 2898 else 2899 currLogicalTopOffset += blockDelta; 2900 2901 LayoutSize offset; 2902 if (isHorizontal) { 2903 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) 2904 offset = LayoutSize(currLogicalLeftOffset, currLogicalTopOffset); 2905 else 2906 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop()); 2907 } else { 2908 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) 2909 offset = LayoutSize(currLogicalTopOffset, currLogicalLeftOffset); 2910 else 2911 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0); 2912 } 2913 2914 colRect.moveBy(layerOffset); 2915 2916 LayoutRect localClipRect(hitTestRect); 2917 localClipRect.intersect(colRect); 2918 2919 if (!localClipRect.isEmpty() && hitTestLocation.intersects(localClipRect)) { 2920 RenderLayer* hitLayer = 0; 2921 if (!columnIndex) { 2922 // Apply a translation transform to change where the layer paints. 2923 TransformationMatrix oldTransform; 2924 bool oldHasTransform = childLayer->transform(); 2925 if (oldHasTransform) 2926 oldTransform = *childLayer->transform(); 2927 TransformationMatrix newTransform(oldTransform); 2928 newTransform.translateRight(offset.width(), offset.height()); 2929 2930 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform)); 2931 hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestLocation, false, transformState, zOffset); 2932 if (oldHasTransform) 2933 childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform)); 2934 else 2935 childLayer->m_transform.clear(); 2936 } else { 2937 // Adjust the transform such that the renderer's upper left corner will be at (0,0) in user space. 2938 // This involves subtracting out the position of the layer in our current coordinate space. 2939 RenderLayer* nextLayer = columnLayers[columnIndex - 1]; 2940 RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestLocation, transformState); 2941 newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform); 2942 FloatPoint localPoint = newTransformState->mappedPoint(); 2943 FloatQuad localPointQuad = newTransformState->mappedQuad(); 2944 LayoutRect localHitTestRect = newTransformState->mappedArea().enclosingBoundingBox(); 2945 HitTestLocation newHitTestLocation; 2946 if (hitTestLocation.isRectBasedTest()) 2947 newHitTestLocation = HitTestLocation(localPoint, localPointQuad); 2948 else 2949 newHitTestLocation = HitTestLocation(localPoint); 2950 newTransformState->flatten(); 2951 2952 hitLayer = hitTestChildLayerColumns(childLayer, columnLayers[columnIndex - 1], request, result, localHitTestRect, newHitTestLocation, 2953 newTransformState.get(), zOffset, columnLayers, columnIndex - 1); 2954 } 2955 2956 if (hitLayer) 2957 return hitLayer; 2958 } 2959 } 2960 2961 return 0; 2962 } 2963 2964 void RenderLayer::blockSelectionGapsBoundsChanged() 2965 { 2966 setNeedsCompositingInputsUpdate(); 2967 } 2968 2969 void RenderLayer::addBlockSelectionGapsBounds(const LayoutRect& bounds) 2970 { 2971 m_blockSelectionGapsBounds.unite(enclosingIntRect(bounds)); 2972 blockSelectionGapsBoundsChanged(); 2973 } 2974 2975 void RenderLayer::clearBlockSelectionGapsBounds() 2976 { 2977 m_blockSelectionGapsBounds = IntRect(); 2978 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 2979 child->clearBlockSelectionGapsBounds(); 2980 blockSelectionGapsBoundsChanged(); 2981 } 2982 2983 void RenderLayer::invalidatePaintForBlockSelectionGaps() 2984 { 2985 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 2986 child->invalidatePaintForBlockSelectionGaps(); 2987 2988 if (m_blockSelectionGapsBounds.isEmpty()) 2989 return; 2990 2991 LayoutRect rect = m_blockSelectionGapsBounds; 2992 if (renderer()->hasOverflowClip()) { 2993 RenderBox* box = renderBox(); 2994 rect.move(-box->scrolledContentOffset()); 2995 if (!scrollableArea()->usesCompositedScrolling()) 2996 rect.intersect(box->overflowClipRect(LayoutPoint())); 2997 } 2998 if (renderer()->hasClip()) 2999 rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint())); 3000 if (!rect.isEmpty()) 3001 renderer()->invalidatePaintRectangle(rect); 3002 } 3003 3004 IntRect RenderLayer::blockSelectionGapsBounds() const 3005 { 3006 if (!renderer()->isRenderBlock()) 3007 return IntRect(); 3008 3009 RenderBlock* renderBlock = toRenderBlock(renderer()); 3010 LayoutRect gapRects = renderBlock->selectionGapRectsForPaintInvalidation(renderBlock); 3011 3012 return pixelSnappedIntRect(gapRects); 3013 } 3014 3015 bool RenderLayer::hasBlockSelectionGapBounds() const 3016 { 3017 // FIXME: it would be more accurate to return !blockSelectionGapsBounds().isEmpty(), but this is impossible 3018 // at the moment because it causes invalid queries to layout-dependent code (crbug.com/372802). 3019 // ASSERT(renderer()->document().lifecycle().state() >= DocumentLifecycle::LayoutClean); 3020 3021 if (!renderer()->isRenderBlock()) 3022 return false; 3023 3024 return toRenderBlock(renderer())->shouldPaintSelectionGaps(); 3025 } 3026 3027 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot) const 3028 { 3029 // Always examine the canvas and the root. 3030 // FIXME: Could eliminate the isDocumentElement() check if we fix background painting so that the RenderView 3031 // paints the root's background. 3032 if (isRootLayer() || renderer()->isDocumentElement()) 3033 return true; 3034 3035 // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we 3036 // can go ahead and return true. 3037 RenderView* view = renderer()->view(); 3038 ASSERT(view); 3039 if (view && !renderer()->isRenderInline()) { 3040 if (layerBounds.intersects(damageRect)) 3041 return true; 3042 } 3043 3044 // Otherwise we need to compute the bounding box of this single layer and see if it intersects 3045 // the damage rect. 3046 return physicalBoundingBox(rootLayer, offsetFromRoot).intersects(damageRect); 3047 } 3048 3049 LayoutRect RenderLayer::logicalBoundingBox() const 3050 { 3051 // There are three special cases we need to consider. 3052 // (1) Inline Flows. For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the 3053 // inline. In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the 3054 // line boxes of all three lines (including overflow on those lines). 3055 // (2) Left/Top Overflow. The width/height of layers already includes right/bottom overflow. However, in the case of left/top 3056 // overflow, we have to create a bounding box that will extend to include this overflow. 3057 // (3) Floats. When a layer has overhanging floats that it paints, we need to make sure to include these overhanging floats 3058 // as part of our bounding box. We do this because we are the responsible layer for both hit testing and painting those 3059 // floats. 3060 LayoutRect result; 3061 if (renderer()->isInline() && renderer()->isRenderInline()) { 3062 result = toRenderInline(renderer())->linesVisualOverflowBoundingBox(); 3063 } else if (renderer()->isTableRow()) { 3064 // Our bounding box is just the union of all of our cells' border/overflow rects. 3065 for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) { 3066 if (child->isTableCell()) { 3067 LayoutRect bbox = toRenderBox(child)->borderBoxRect(); 3068 result.unite(bbox); 3069 LayoutRect overflowRect = renderBox()->visualOverflowRect(); 3070 if (bbox != overflowRect) 3071 result.unite(overflowRect); 3072 } 3073 } 3074 } else { 3075 RenderBox* box = renderBox(); 3076 ASSERT(box); 3077 result = box->borderBoxRect(); 3078 result.unite(box->visualOverflowRect()); 3079 } 3080 3081 ASSERT(renderer()->view()); 3082 return result; 3083 } 3084 3085 LayoutRect RenderLayer::physicalBoundingBox(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot) const 3086 { 3087 LayoutRect result = logicalBoundingBox(); 3088 if (m_renderer->isBox()) 3089 renderBox()->flipForWritingMode(result); 3090 else 3091 m_renderer->containingBlock()->flipForWritingMode(result); 3092 3093 LayoutPoint delta; 3094 if (offsetFromRoot) 3095 delta = *offsetFromRoot; 3096 else 3097 convertToLayerCoords(ancestorLayer, delta); 3098 3099 result.moveBy(delta); 3100 return result; 3101 } 3102 3103 static void expandRectForReflectionAndStackingChildren(const RenderLayer* ancestorLayer, RenderLayer::CalculateBoundsOptions options, LayoutRect& result) 3104 { 3105 if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) 3106 result.unite(ancestorLayer->reflectionInfo()->reflectionLayer()->boundingBoxForCompositing(ancestorLayer)); 3107 3108 ASSERT(ancestorLayer->stackingNode()->isStackingContext() || !ancestorLayer->stackingNode()->hasPositiveZOrderList()); 3109 3110 #if ENABLE(ASSERT) 3111 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(ancestorLayer)->stackingNode()); 3112 #endif 3113 3114 RenderLayerStackingNodeIterator iterator(*ancestorLayer->stackingNode(), AllChildren); 3115 while (RenderLayerStackingNode* node = iterator.next()) { 3116 // Here we exclude both directly composited layers and squashing layers 3117 // because those RenderLayers don't paint into the graphics layer 3118 // for this RenderLayer. For example, the bounds of squashed RenderLayers 3119 // will be included in the computation of the appropriate squashing 3120 // GraphicsLayer. 3121 if (options != RenderLayer::ApplyBoundsChickenEggHacks && node->layer()->compositingState() != NotComposited) 3122 continue; 3123 result.unite(node->layer()->boundingBoxForCompositing(ancestorLayer, options)); 3124 } 3125 } 3126 3127 LayoutRect RenderLayer::physicalBoundingBoxIncludingReflectionAndStackingChildren(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const 3128 { 3129 LayoutPoint origin; 3130 LayoutRect result = physicalBoundingBox(ancestorLayer, &origin); 3131 3132 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded(); 3133 3134 expandRectForReflectionAndStackingChildren(this, DoNotApplyBoundsChickenEggHacks, result); 3135 3136 result.moveBy(offsetFromRoot); 3137 return result; 3138 } 3139 3140 LayoutRect RenderLayer::boundingBoxForCompositing(const RenderLayer* ancestorLayer, CalculateBoundsOptions options) const 3141 { 3142 if (!isSelfPaintingLayer()) 3143 return LayoutRect(); 3144 3145 if (!ancestorLayer) 3146 ancestorLayer = this; 3147 3148 // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580). 3149 if (this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant()) 3150 return LayoutRect(); 3151 3152 // The root layer is always just the size of the document. 3153 if (isRootLayer()) 3154 return m_renderer->view()->unscaledDocumentRect(); 3155 3156 const bool shouldIncludeTransform = paintsWithTransform(PaintBehaviorNormal) || (options == ApplyBoundsChickenEggHacks && transform()); 3157 3158 LayoutRect localClipRect = clipper().localClipRect(); 3159 if (localClipRect != PaintInfo::infiniteRect()) { 3160 if (shouldIncludeTransform) 3161 localClipRect = transform()->mapRect(localClipRect); 3162 3163 LayoutPoint delta; 3164 convertToLayerCoords(ancestorLayer, delta); 3165 localClipRect.moveBy(delta); 3166 return localClipRect; 3167 } 3168 3169 LayoutPoint origin; 3170 LayoutRect result = physicalBoundingBox(ancestorLayer, &origin); 3171 3172 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded(); 3173 3174 // Reflections are implemented with RenderLayers that hang off of the reflected layer. However, 3175 // the reflection layer subtree does not include the subtree of the parent RenderLayer, so 3176 // a recursive computation of stacking children yields no results. This breaks cases when there are stacking 3177 // children of the parent, that need to be included in reflected composited bounds. 3178 // Fix this by including composited bounds of stacking children of the reflected RenderLayer. 3179 if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo() && parent()->reflectionInfo()->reflectionLayer() == this) 3180 expandRectForReflectionAndStackingChildren(parent(), options, result); 3181 else 3182 expandRectForReflectionAndStackingChildren(this, options, result); 3183 3184 // FIXME: We can optimize the size of the composited layers, by not enlarging 3185 // filtered areas with the outsets if we know that the filter is going to render in hardware. 3186 // https://bugs.webkit.org/show_bug.cgi?id=81239 3187 m_renderer->style()->filterOutsets().expandRect(result); 3188 3189 if (shouldIncludeTransform) 3190 result = transform()->mapRect(result); 3191 3192 LayoutPoint delta; 3193 convertToLayerCoords(ancestorLayer, delta); 3194 result.moveBy(delta); 3195 return result; 3196 } 3197 3198 CompositingState RenderLayer::compositingState() const 3199 { 3200 ASSERT(isAllowedToQueryCompositingState()); 3201 3202 // This is computed procedurally so there is no redundant state variable that 3203 // can get out of sync from the real actual compositing state. 3204 3205 if (m_groupedMapping) { 3206 ASSERT(compositor()->layerSquashingEnabled()); 3207 ASSERT(!m_compositedLayerMapping); 3208 return PaintsIntoGroupedBacking; 3209 } 3210 3211 if (!m_compositedLayerMapping) 3212 return NotComposited; 3213 3214 if (compositedLayerMapping()->paintsIntoCompositedAncestor()) 3215 return HasOwnBackingButPaintsIntoAncestor; 3216 3217 return PaintsIntoOwnBacking; 3218 } 3219 3220 bool RenderLayer::isAllowedToQueryCompositingState() const 3221 { 3222 if (gCompositingQueryMode == CompositingQueriesAreAllowed) 3223 return true; 3224 return renderer()->document().lifecycle().state() >= DocumentLifecycle::InCompositingUpdate; 3225 } 3226 3227 CompositedLayerMapping* RenderLayer::compositedLayerMapping() const 3228 { 3229 ASSERT(isAllowedToQueryCompositingState()); 3230 return m_compositedLayerMapping.get(); 3231 } 3232 3233 GraphicsLayer* RenderLayer::graphicsLayerBacking() const 3234 { 3235 switch (compositingState()) { 3236 case NotComposited: 3237 return 0; 3238 case PaintsIntoGroupedBacking: 3239 return groupedMapping()->squashingLayer(); 3240 default: 3241 return compositedLayerMapping()->mainGraphicsLayer(); 3242 } 3243 } 3244 3245 GraphicsLayer* RenderLayer::graphicsLayerBackingForScrolling() const 3246 { 3247 switch (compositingState()) { 3248 case NotComposited: 3249 return 0; 3250 case PaintsIntoGroupedBacking: 3251 return groupedMapping()->squashingLayer(); 3252 default: 3253 return compositedLayerMapping()->scrollingContentsLayer() ? compositedLayerMapping()->scrollingContentsLayer() : compositedLayerMapping()->mainGraphicsLayer(); 3254 } 3255 } 3256 3257 CompositedLayerMapping* RenderLayer::ensureCompositedLayerMapping() 3258 { 3259 if (!m_compositedLayerMapping) { 3260 m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(*this)); 3261 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); 3262 3263 updateOrRemoveFilterEffectRenderer(); 3264 } 3265 return m_compositedLayerMapping.get(); 3266 } 3267 3268 void RenderLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) 3269 { 3270 if (!layerBeingDestroyed) { 3271 // We need to make sure our decendants get a geometry update. In principle, 3272 // we could call setNeedsGraphicsLayerUpdate on our children, but that would 3273 // require walking the z-order lists to find them. Instead, we over-invalidate 3274 // by marking our parent as needing a geometry update. 3275 if (RenderLayer* compositingParent = enclosingLayerWithCompositedLayerMapping(ExcludeSelf)) 3276 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); 3277 } 3278 3279 m_compositedLayerMapping.clear(); 3280 3281 if (!layerBeingDestroyed) 3282 updateOrRemoveFilterEffectRenderer(); 3283 } 3284 3285 void RenderLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layerBeingDestroyed) 3286 { 3287 if (groupedMapping == m_groupedMapping) 3288 return; 3289 3290 if (!layerBeingDestroyed && m_groupedMapping) { 3291 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); 3292 m_groupedMapping->removeRenderLayerFromSquashingGraphicsLayer(this); 3293 } 3294 m_groupedMapping = groupedMapping; 3295 if (!layerBeingDestroyed && m_groupedMapping) 3296 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); 3297 } 3298 3299 bool RenderLayer::hasCompositedMask() const 3300 { 3301 return m_compositedLayerMapping && m_compositedLayerMapping->hasMaskLayer(); 3302 } 3303 3304 bool RenderLayer::hasCompositedClippingMask() const 3305 { 3306 return m_compositedLayerMapping && m_compositedLayerMapping->hasChildClippingMaskLayer(); 3307 } 3308 3309 bool RenderLayer::clipsCompositingDescendantsWithBorderRadius() const 3310 { 3311 RenderStyle* style = renderer()->style(); 3312 if (!style) 3313 return false; 3314 3315 return compositor()->clipsCompositingDescendants(this) && style->hasBorderRadius(); 3316 } 3317 3318 bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const 3319 { 3320 return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || compositingState() != PaintsIntoOwnBacking); 3321 } 3322 3323 bool RenderLayer::paintsWithBlendMode() const 3324 { 3325 return m_renderer->hasBlendMode() && compositingState() != PaintsIntoOwnBacking; 3326 } 3327 3328 bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const 3329 { 3330 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) 3331 return false; 3332 3333 if (paintsWithTransparency(PaintBehaviorNormal)) 3334 return false; 3335 3336 // We can't use hasVisibleContent(), because that will be true if our renderer is hidden, but some child 3337 // is visible and that child doesn't cover the entire rect. 3338 if (renderer()->style()->visibility() != VISIBLE) 3339 return false; 3340 3341 if (paintsWithFilters() && renderer()->style()->filter().hasFilterThatAffectsOpacity()) 3342 return false; 3343 3344 // FIXME: Handle simple transforms. 3345 if (paintsWithTransform(PaintBehaviorNormal)) 3346 return false; 3347 3348 // FIXME: Remove this check. 3349 // This function should not be called when layer-lists are dirty. 3350 // It is somehow getting triggered during style update. 3351 if (m_stackingNode->zOrderListsDirty() || m_stackingNode->normalFlowListDirty()) 3352 return false; 3353 3354 // FIXME: We currently only check the immediate renderer, 3355 // which will miss many cases. 3356 if (renderer()->backgroundIsKnownToBeOpaqueInRect(localRect)) 3357 return true; 3358 3359 // We can't consult child layers if we clip, since they might cover 3360 // parts of the rect that are clipped out. 3361 if (renderer()->hasOverflowClip()) 3362 return false; 3363 3364 return childBackgroundIsKnownToBeOpaqueInRect(localRect); 3365 } 3366 3367 bool RenderLayer::childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const 3368 { 3369 RenderLayerStackingNodeReverseIterator revertseIterator(*m_stackingNode, PositiveZOrderChildren | NormalFlowChildren | NegativeZOrderChildren); 3370 while (RenderLayerStackingNode* child = revertseIterator.next()) { 3371 const RenderLayer* childLayer = child->layer(); 3372 // Stop at composited paint boundaries. 3373 if (childLayer->isPaintInvalidationContainer()) 3374 continue; 3375 3376 if (!childLayer->canUseConvertToLayerCoords()) 3377 continue; 3378 3379 LayoutPoint childOffset; 3380 LayoutRect childLocalRect(localRect); 3381 childLayer->convertToLayerCoords(this, childOffset); 3382 childLocalRect.moveBy(-childOffset); 3383 3384 if (childLayer->backgroundIsKnownToBeOpaqueInRect(childLocalRect)) 3385 return true; 3386 } 3387 return false; 3388 } 3389 3390 bool RenderLayer::shouldBeSelfPaintingLayer() const 3391 { 3392 if (renderer()->isRenderPart() && toRenderPart(renderer())->requiresAcceleratedCompositing()) 3393 return true; 3394 return m_layerType == NormalLayer 3395 || (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars()) 3396 || needsCompositedScrolling(); 3397 } 3398 3399 void RenderLayer::updateSelfPaintingLayer() 3400 { 3401 bool isSelfPaintingLayer = shouldBeSelfPaintingLayer(); 3402 if (this->isSelfPaintingLayer() == isSelfPaintingLayer) 3403 return; 3404 3405 m_isSelfPaintingLayer = isSelfPaintingLayer; 3406 3407 if (parent()) 3408 parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 3409 } 3410 3411 bool RenderLayer::hasNonEmptyChildRenderers() const 3412 { 3413 // Some HTML can cause whitespace text nodes to have renderers, like: 3414 // <div> 3415 // <img src=...> 3416 // </div> 3417 // so test for 0x0 RenderTexts here 3418 for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) { 3419 if (!child->hasLayer()) { 3420 if (child->isRenderInline() || !child->isBox()) 3421 return true; 3422 3423 if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0) 3424 return true; 3425 } 3426 } 3427 return false; 3428 } 3429 3430 bool RenderLayer::hasBoxDecorationsOrBackground() const 3431 { 3432 return renderer()->style()->hasBoxDecorations() || renderer()->style()->hasBackground(); 3433 } 3434 3435 bool RenderLayer::hasVisibleBoxDecorations() const 3436 { 3437 if (!hasVisibleContent()) 3438 return false; 3439 3440 return hasBoxDecorationsOrBackground() || hasOverflowControls(); 3441 } 3442 3443 bool RenderLayer::isVisuallyNonEmpty() const 3444 { 3445 ASSERT(!m_visibleDescendantStatusDirty); 3446 3447 if (hasVisibleContent() && hasNonEmptyChildRenderers()) 3448 return true; 3449 3450 if (renderer()->isReplaced() || renderer()->hasMask()) 3451 return true; 3452 3453 if (hasVisibleBoxDecorations()) 3454 return true; 3455 3456 return false; 3457 } 3458 3459 void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle) 3460 { 3461 if (!newStyle->hasFilter() && (!oldStyle || !oldStyle->hasFilter())) 3462 return; 3463 3464 updateOrRemoveFilterClients(); 3465 updateOrRemoveFilterEffectRenderer(); 3466 } 3467 3468 bool RenderLayer::attemptDirectCompositingUpdate(StyleDifference diff, const RenderStyle* oldStyle) 3469 { 3470 CompositingReasons oldPotentialCompositingReasonsFromStyle = m_potentialCompositingReasonsFromStyle; 3471 compositor()->updatePotentialCompositingReasonsFromStyle(this); 3472 3473 // This function implements an optimization for transforms and opacity. 3474 // A common pattern is for a touchmove handler to update the transform 3475 // and/or an opacity of an element every frame while the user moves their 3476 // finger across the screen. The conditions below recognize when the 3477 // compositing state is set up to receive a direct transform or opacity 3478 // update. 3479 3480 if (!diff.hasAtMostPropertySpecificDifferences(StyleDifference::TransformChanged | StyleDifference::OpacityChanged)) 3481 return false; 3482 // The potentialCompositingReasonsFromStyle could have changed without 3483 // a corresponding StyleDifference if an animation started or ended. 3484 if (m_potentialCompositingReasonsFromStyle != oldPotentialCompositingReasonsFromStyle) 3485 return false; 3486 // We could add support for reflections if we updated the transform on 3487 // the reflection layers. 3488 if (renderer()->hasReflection()) 3489 return false; 3490 // If we're unwinding a scheduleSVGFilterLayerUpdateHack(), then we can't 3491 // perform a direct compositing update because the filters code is going 3492 // to produce different output this time around. We can remove this code 3493 // once we fix the chicken/egg bugs in the filters code and delete the 3494 // scheduleSVGFilterLayerUpdateHack(). 3495 if (renderer()->node() && renderer()->node()->svgFilterNeedsLayerUpdate()) 3496 return false; 3497 if (!m_compositedLayerMapping) 3498 return false; 3499 3500 // To cut off almost all the work in the compositing update for 3501 // this case, we treat inline transforms has having assumed overlap 3502 // (similar to how we treat animated transforms). Notice that we read 3503 // CompositingReasonInlineTransform from the m_compositingReasons, which 3504 // means that the inline transform actually triggered assumed overlap in 3505 // the overlap map. 3506 if (diff.transformChanged() && !(m_compositingReasons & CompositingReasonInlineTransform)) 3507 return false; 3508 3509 // We composite transparent RenderLayers differently from non-transparent 3510 // RenderLayers even when the non-transparent RenderLayers are already a 3511 // stacking context. 3512 if (diff.opacityChanged() && m_renderer->style()->hasOpacity() != oldStyle->hasOpacity()) 3513 return false; 3514 3515 updateTransform(oldStyle, renderer()->style()); 3516 3517 // FIXME: Consider introducing a smaller graphics layer update scope 3518 // that just handles transforms and opacity. GraphicsLayerUpdateLocal 3519 // will also program bounds, clips, and many other properties that could 3520 // not possibly have changed. 3521 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal); 3522 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterGeometryChange); 3523 return true; 3524 } 3525 3526 void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle) 3527 { 3528 if (attemptDirectCompositingUpdate(diff, oldStyle)) 3529 return; 3530 3531 m_stackingNode->updateIsNormalFlowOnly(); 3532 m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle); 3533 3534 if (m_scrollableArea) 3535 m_scrollableArea->updateAfterStyleChange(oldStyle); 3536 3537 // Overlay scrollbars can make this layer self-painting so we need 3538 // to recompute the bit once scrollbars have been updated. 3539 updateSelfPaintingLayer(); 3540 3541 if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) { 3542 ASSERT(!oldStyle || diff.needsFullLayout()); 3543 updateReflectionInfo(oldStyle); 3544 } 3545 3546 updateDescendantDependentFlags(); 3547 3548 updateTransform(oldStyle, renderer()->style()); 3549 updateFilters(oldStyle, renderer()->style()); 3550 3551 setNeedsCompositingInputsUpdate(); 3552 } 3553 3554 bool RenderLayer::scrollsOverflow() const 3555 { 3556 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea()) 3557 return scrollableArea->scrollsOverflow(); 3558 3559 return false; 3560 } 3561 3562 FilterOperations RenderLayer::computeFilterOperations(const RenderStyle* style) 3563 { 3564 const FilterOperations& filters = style->filter(); 3565 if (filters.hasReferenceFilter()) { 3566 for (size_t i = 0; i < filters.size(); ++i) { 3567 FilterOperation* filterOperation = filters.operations().at(i).get(); 3568 if (filterOperation->type() != FilterOperation::REFERENCE) 3569 continue; 3570 ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation); 3571 // FIXME: Cache the ReferenceFilter if it didn't change. 3572 RefPtr<ReferenceFilter> referenceFilter = ReferenceFilter::create(); 3573 float zoom = style->effectiveZoom(); 3574 referenceFilter->setAbsoluteTransform(AffineTransform().scale(zoom, zoom)); 3575 referenceFilter->setLastEffect(ReferenceFilterBuilder::build(referenceFilter.get(), renderer(), referenceFilter->sourceGraphic(), 3576 referenceOperation)); 3577 referenceOperation->setFilter(referenceFilter.release()); 3578 } 3579 } 3580 3581 return filters; 3582 } 3583 3584 void RenderLayer::updateOrRemoveFilterClients() 3585 { 3586 if (!hasFilter()) { 3587 removeFilterInfoIfNeeded(); 3588 return; 3589 } 3590 3591 if (renderer()->style()->filter().hasReferenceFilter()) 3592 ensureFilterInfo()->updateReferenceFilterClients(renderer()->style()->filter()); 3593 else if (hasFilterInfo()) 3594 filterInfo()->removeReferenceFilterClients(); 3595 } 3596 3597 void RenderLayer::updateOrRemoveFilterEffectRenderer() 3598 { 3599 // FilterEffectRenderer is only used to render the filters in software mode, 3600 // so we always need to run updateOrRemoveFilterEffectRenderer after the composited 3601 // mode might have changed for this layer. 3602 if (!paintsWithFilters()) { 3603 // Don't delete the whole filter info here, because we might use it 3604 // for loading CSS shader files. 3605 if (RenderLayerFilterInfo* filterInfo = this->filterInfo()) 3606 filterInfo->setRenderer(nullptr); 3607 3608 return; 3609 } 3610 3611 RenderLayerFilterInfo* filterInfo = ensureFilterInfo(); 3612 if (!filterInfo->renderer()) { 3613 RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create(); 3614 filterInfo->setRenderer(filterRenderer.release()); 3615 } 3616 3617 // If the filter fails to build, remove it from the layer. It will still attempt to 3618 // go through regular processing (e.g. compositing), but never apply anything. 3619 if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(renderer()->style()))) 3620 filterInfo->setRenderer(nullptr); 3621 } 3622 3623 void RenderLayer::filterNeedsPaintInvalidation() 3624 { 3625 { 3626 DeprecatedScheduleStyleRecalcDuringLayout marker(renderer()->document().lifecycle()); 3627 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style recalc, which 3628 // is a problem because this function can be called while performing layout. 3629 // Presumably this represents an illegal data flow of layout or compositing 3630 // information into the style system. 3631 toElement(renderer()->node())->scheduleSVGFilterLayerUpdateHack(); 3632 } 3633 3634 renderer()->setShouldDoFullPaintInvalidation(true); 3635 } 3636 3637 void RenderLayer::addLayerHitTestRects(LayerHitTestRects& rects) const 3638 { 3639 computeSelfHitTestRects(rects); 3640 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 3641 child->addLayerHitTestRects(rects); 3642 } 3643 3644 void RenderLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const 3645 { 3646 if (!size().isEmpty()) { 3647 Vector<LayoutRect> rect; 3648 3649 if (renderBox() && renderBox()->scrollsOverflow()) { 3650 // For scrolling layers, rects are taken to be in the space of the contents. 3651 // We need to include the bounding box of the layer in the space of its parent 3652 // (eg. for border / scroll bars) and if it's composited then the entire contents 3653 // as well as they may be on another composited layer. Skip reporting contents 3654 // for non-composited layers as they'll get projected to the same layer as the 3655 // bounding box. 3656 if (compositingState() != NotComposited) 3657 rect.append(m_scrollableArea->overflowRect()); 3658 3659 rects.set(this, rect); 3660 if (const RenderLayer* parentLayer = parent()) { 3661 LayerHitTestRects::iterator iter = rects.find(parentLayer); 3662 if (iter == rects.end()) { 3663 rects.add(parentLayer, Vector<LayoutRect>()).storedValue->value.append(physicalBoundingBox(parentLayer)); 3664 } else { 3665 iter->value.append(physicalBoundingBox(parentLayer)); 3666 } 3667 } 3668 } else { 3669 rect.append(logicalBoundingBox()); 3670 rects.set(this, rect); 3671 } 3672 } 3673 } 3674 3675 void RenderLayer::setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants() 3676 { 3677 renderer()->setShouldDoFullPaintInvalidation(true); 3678 3679 // Disable for reading compositingState() in isPaintInvalidationContainer() below. 3680 DisableCompositingQueryAsserts disabler; 3681 3682 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { 3683 if (!child->isPaintInvalidationContainer()) 3684 child->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants(); 3685 } 3686 } 3687 3688 DisableCompositingQueryAsserts::DisableCompositingQueryAsserts() 3689 : m_disabler(gCompositingQueryMode, CompositingQueriesAreAllowed) { } 3690 3691 } // namespace blink 3692 3693 #ifndef NDEBUG 3694 void showLayerTree(const blink::RenderLayer* layer) 3695 { 3696 if (!layer) 3697 return; 3698 3699 if (blink::LocalFrame* frame = layer->renderer()->frame()) { 3700 WTF::String output = externalRepresentation(frame, blink::RenderAsTextShowAllLayers | blink::RenderAsTextShowLayerNesting | blink::RenderAsTextShowCompositedLayers | blink::RenderAsTextShowAddresses | blink::RenderAsTextShowIDAndClass | blink::RenderAsTextDontUpdateLayout | blink::RenderAsTextShowLayoutState); 3701 fprintf(stderr, "%s\n", output.utf8().data()); 3702 } 3703 } 3704 3705 void showLayerTree(const blink::RenderObject* renderer) 3706 { 3707 if (!renderer) 3708 return; 3709 showLayerTree(renderer->enclosingLayer()); 3710 } 3711 #endif 3712