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 "CSSPropertyNames.h" 48 #include "HTMLNames.h" 49 #include "RuntimeEnabledFeatures.h" 50 #include "SVGNames.h" 51 #include "core/animation/ActiveAnimations.h" 52 #include "core/css/PseudoStyleRequest.h" 53 #include "core/dom/Document.h" 54 #include "core/dom/shadow/ShadowRoot.h" 55 #include "core/html/HTMLFrameElement.h" 56 #include "core/frame/Frame.h" 57 #include "core/frame/FrameView.h" 58 #include "core/page/Page.h" 59 #include "core/frame/Settings.h" 60 #include "core/frame/animation/AnimationController.h" 61 #include "core/page/scrolling/ScrollingCoordinator.h" 62 #include "core/rendering/ColumnInfo.h" 63 #include "core/rendering/CompositedLayerMapping.h" 64 #include "core/rendering/FilterEffectRenderer.h" 65 #include "core/rendering/HitTestRequest.h" 66 #include "core/rendering/HitTestResult.h" 67 #include "core/rendering/HitTestingTransformState.h" 68 #include "core/rendering/RenderFlowThread.h" 69 #include "core/rendering/RenderGeometryMap.h" 70 #include "core/rendering/RenderInline.h" 71 #include "core/rendering/RenderLayerCompositor.h" 72 #include "core/rendering/RenderReplica.h" 73 #include "core/rendering/RenderScrollbar.h" 74 #include "core/rendering/RenderScrollbarPart.h" 75 #include "core/rendering/RenderTreeAsText.h" 76 #include "core/rendering/RenderView.h" 77 #include "core/rendering/svg/ReferenceFilterBuilder.h" 78 #include "core/rendering/svg/RenderSVGResourceClipper.h" 79 #include "platform/LengthFunctions.h" 80 #include "platform/Partitions.h" 81 #include "platform/TraceEvent.h" 82 #include "platform/geometry/FloatPoint3D.h" 83 #include "platform/geometry/FloatRect.h" 84 #include "platform/graphics/GraphicsContextStateSaver.h" 85 #include "platform/graphics/filters/ReferenceFilter.h" 86 #include "platform/graphics/filters/SourceGraphic.h" 87 #include "platform/graphics/filters/custom/CustomFilterGlobalContext.h" 88 #include "platform/graphics/filters/custom/CustomFilterOperation.h" 89 #include "platform/graphics/filters/custom/CustomFilterValidatedProgram.h" 90 #include "platform/graphics/filters/custom/ValidatedCustomFilterOperation.h" 91 #include "platform/transforms/ScaleTransformOperation.h" 92 #include "platform/transforms/TransformationMatrix.h" 93 #include "platform/transforms/TranslateTransformOperation.h" 94 #include "public/platform/Platform.h" 95 #include "wtf/StdLibExtras.h" 96 #include "wtf/text/CString.h" 97 98 using namespace std; 99 100 namespace WebCore { 101 102 using namespace HTMLNames; 103 104 RenderLayer::RenderLayer(RenderLayerModelObject* renderer) 105 : m_hasSelfPaintingLayerDescendant(false) 106 , m_hasSelfPaintingLayerDescendantDirty(false) 107 , m_hasOutOfFlowPositionedDescendant(false) 108 , m_hasOutOfFlowPositionedDescendantDirty(true) 109 , m_hasUnclippedDescendant(false) 110 , m_isUnclippedDescendant(false) 111 , m_isRootLayer(renderer->isRenderView()) 112 , m_usedTransparency(false) 113 , m_childLayerHasBlendMode(false) 114 , m_childLayerHasBlendModeStatusDirty(false) 115 , m_visibleContentStatusDirty(true) 116 , m_hasVisibleContent(false) 117 , m_visibleDescendantStatusDirty(false) 118 , m_hasVisibleDescendant(false) 119 , m_hasVisibleNonLayerContent(false) 120 , m_isPaginated(false) 121 , m_3DTransformedDescendantStatusDirty(true) 122 , m_has3DTransformedDescendant(false) 123 , m_containsDirtyOverlayScrollbars(false) 124 , m_canSkipRepaintRectsUpdateOnScroll(renderer->isTableCell()) 125 , m_hasFilterInfo(false) 126 , m_blendMode(blink::WebBlendModeNormal) 127 , m_renderer(renderer) 128 , m_parent(0) 129 , m_previous(0) 130 , m_next(0) 131 , m_first(0) 132 , m_last(0) 133 , m_staticInlinePosition(0) 134 , m_staticBlockPosition(0) 135 , m_enclosingPaginationLayer(0) 136 , m_groupedMapping(0) 137 , m_repainter(renderer) 138 , m_clipper(renderer) 139 { 140 updateStackingNode(); 141 142 m_isSelfPaintingLayer = shouldBeSelfPaintingLayer(); 143 144 if (!renderer->firstChild() && renderer->style()) { 145 m_visibleContentStatusDirty = false; 146 m_hasVisibleContent = renderer->style()->visibility() == VISIBLE; 147 } 148 149 updateScrollableArea(); 150 } 151 152 RenderLayer::~RenderLayer() 153 { 154 if (!m_renderer->documentBeingDestroyed()) 155 compositor()->removeOutOfFlowPositionedLayer(this); 156 157 if (renderer()->frame() && renderer()->frame()->page()) { 158 if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->page()->scrollingCoordinator()) 159 scrollingCoordinator->willDestroyRenderLayer(this); 160 } 161 162 removeFilterInfoIfNeeded(); 163 164 // Child layers will be deleted by their corresponding render objects, so 165 // we don't need to delete them ourselves. 166 167 clearCompositedLayerMapping(true); 168 } 169 170 String RenderLayer::debugName() const 171 { 172 if (isReflection()) 173 return m_reflectionInfo->debugName(); 174 return renderer()->debugName(); 175 } 176 177 RenderLayerCompositor* RenderLayer::compositor() const 178 { 179 if (!renderer()->view()) 180 return 0; 181 return renderer()->view()->compositor(); 182 } 183 184 void RenderLayer::contentChanged(ContentChangeType changeType) 185 { 186 // This can get called when video becomes accelerated, so the layers may change. 187 if ((changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged) && compositor()->updateLayerCompositingState(this)) 188 compositor()->setCompositingLayersNeedRebuild(); 189 190 if (m_compositedLayerMapping) 191 m_compositedLayerMapping->contentChanged(changeType); 192 } 193 194 bool RenderLayer::canRender3DTransforms() const 195 { 196 return compositor()->canRender3DTransforms(); 197 } 198 199 bool RenderLayer::paintsWithFilters() const 200 { 201 if (!renderer()->hasFilter()) 202 return false; 203 204 if (compositingState() != PaintsIntoOwnBacking) 205 return true; 206 207 if (!m_compositedLayerMapping || !m_compositedLayerMapping->canCompositeFilters()) 208 return true; 209 210 return false; 211 } 212 213 bool RenderLayer::requiresFullLayerImageForFilters() const 214 { 215 if (!paintsWithFilters()) 216 return false; 217 FilterEffectRenderer* filter = filterRenderer(); 218 return filter ? filter->hasFilterThatMovesPixels() : false; 219 } 220 221 LayoutPoint RenderLayer::computeOffsetFromRoot(bool& hasLayerOffset) const 222 { 223 hasLayerOffset = true; 224 225 if (!parent()) 226 return LayoutPoint(); 227 228 // This is similar to root() but we check if an ancestor layer would 229 // prevent the optimization from working. 230 const RenderLayer* rootLayer = 0; 231 for (const RenderLayer* parentLayer = parent(); parentLayer; rootLayer = parentLayer, parentLayer = parentLayer->parent()) { 232 hasLayerOffset = parentLayer->canUseConvertToLayerCoords(); 233 if (!hasLayerOffset) 234 return LayoutPoint(); 235 } 236 ASSERT(rootLayer == root()); 237 238 LayoutPoint offset; 239 parent()->convertToLayerCoords(rootLayer, offset); 240 return offset; 241 } 242 243 void RenderLayer::updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags flags) 244 { 245 RenderGeometryMap geometryMap(UseTransforms); 246 if (this != rootLayer) 247 geometryMap.pushMappingsToAncestor(parent(), 0); 248 updateLayerPositions(&geometryMap, flags); 249 } 250 251 void RenderLayer::updateLayerPositions(RenderGeometryMap* geometryMap, UpdateLayerPositionsFlags flags) 252 { 253 updateLayerPosition(); // For relpositioned layers or non-positioned layers, 254 // we need to keep in sync, since we may have shifted relative 255 // to our parent layer. 256 if (geometryMap) 257 geometryMap->pushMappingsToAncestor(this, parent()); 258 259 // Clear our cached clip rect information. 260 m_clipper.clearClipRects(); 261 262 if (hasOverflowControls()) { 263 LayoutPoint offsetFromRoot; 264 if (geometryMap) 265 offsetFromRoot = LayoutPoint(geometryMap->absolutePoint(FloatPoint())); 266 else { 267 // FIXME: It looks suspicious to call convertToLayerCoords here 268 // as canUseConvertToLayerCoords may be true for an ancestor layer. 269 convertToLayerCoords(root(), offsetFromRoot); 270 } 271 scrollableArea()->positionOverflowControls(toIntSize(roundedIntPoint(offsetFromRoot))); 272 } 273 274 updateDescendantDependentFlags(); 275 276 if (flags & UpdatePagination) 277 updatePagination(); 278 else { 279 m_isPaginated = false; 280 m_enclosingPaginationLayer = 0; 281 } 282 283 repainter().repaintAfterLayout(geometryMap, flags & CheckForRepaint); 284 285 // Go ahead and update the reflection's position and size. 286 if (m_reflectionInfo) 287 m_reflectionInfo->reflection()->layout(); 288 289 // Clear the IsCompositingUpdateRoot flag once we've found the first compositing layer in this update. 290 bool isUpdateRoot = (flags & IsCompositingUpdateRoot); 291 if (hasCompositedLayerMapping()) 292 flags &= ~IsCompositingUpdateRoot; 293 294 if (useRegionBasedColumns() && renderer()->isInFlowRenderFlowThread()) { 295 updatePagination(); 296 flags |= UpdatePagination; 297 } 298 299 if (renderer()->hasColumns()) 300 flags |= UpdatePagination; 301 302 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 303 child->updateLayerPositions(geometryMap, flags); 304 305 if ((flags & UpdateCompositingLayers) && hasCompositedLayerMapping()) { 306 CompositedLayerMapping::UpdateAfterLayoutFlags updateFlags = CompositedLayerMapping::CompositingChildrenOnly; 307 if (flags & NeedsFullRepaintInBacking) 308 updateFlags |= CompositedLayerMapping::NeedsFullRepaint; 309 if (isUpdateRoot) 310 updateFlags |= CompositedLayerMapping::IsUpdateRoot; 311 compositedLayerMapping()->updateAfterLayout(updateFlags); 312 } 313 314 if (geometryMap) 315 geometryMap->popMappingsToAncestor(parent()); 316 } 317 318 void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant() 319 { 320 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 321 if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaintingLayerDescendant()) 322 break; 323 324 layer->m_hasSelfPaintingLayerDescendantDirty = false; 325 layer->m_hasSelfPaintingLayerDescendant = true; 326 } 327 } 328 329 void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus() 330 { 331 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 332 layer->m_hasSelfPaintingLayerDescendantDirty = true; 333 // If we have reached a self-painting layer, we know our parent should have a self-painting descendant 334 // in this case, there is no need to dirty our ancestors further. 335 if (layer->isSelfPaintingLayer()) { 336 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->hasSelfPaintingLayerDescendant()); 337 break; 338 } 339 } 340 } 341 342 void RenderLayer::setAncestorChainHasOutOfFlowPositionedDescendant() 343 { 344 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 345 if (!layer->m_hasOutOfFlowPositionedDescendantDirty && layer->hasOutOfFlowPositionedDescendant()) 346 break; 347 348 layer->setHasOutOfFlowPositionedDescendantDirty(false); 349 layer->setHasOutOfFlowPositionedDescendant(true); 350 } 351 } 352 353 void RenderLayer::dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus() 354 { 355 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 356 layer->setHasOutOfFlowPositionedDescendantDirty(true); 357 358 // We may or may not have an unclipped descendant. If we do, we'll reset 359 // this to true the next time composited scrolling state is updated. 360 layer->setHasUnclippedDescendant(false); 361 362 // If we have reached an out of flow positioned layer, we know our parent should have an out-of-flow positioned descendant. 363 // In this case, there is no need to dirty our ancestors further. 364 if (layer->renderer()->isOutOfFlowPositioned()) { 365 ASSERT(!parent() || parent()->m_hasOutOfFlowPositionedDescendantDirty || parent()->hasOutOfFlowPositionedDescendant()); 366 break; 367 } 368 } 369 } 370 371 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const 372 { 373 const Settings* settings = renderer()->document().settings(); 374 return settings && settings->acceleratedCompositingForOverflowScrollEnabled(); 375 } 376 377 // FIXME: This is a temporary flag and should be removed once accelerated 378 // overflow scroll is ready (crbug.com/254111). 379 bool RenderLayer::compositorDrivenAcceleratedScrollingEnabled() const 380 { 381 if (!acceleratedCompositingForOverflowScrollEnabled()) 382 return false; 383 384 const Settings* settings = renderer()->document().settings(); 385 return settings && settings->compositorDrivenAcceleratedScrollingEnabled(); 386 } 387 388 bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const 389 { 390 const EPosition position = renderer()->style()->position(); 391 const EPosition otherPosition = other->renderer()->style()->position(); 392 const RenderObject* containingBlock = renderer()->containingBlock(); 393 const RenderObject* otherContainingBlock = other->renderer()->containingBlock(); 394 const RenderLayer* rootLayer = renderer()->view()->compositor()->rootRenderLayer(); 395 396 // Fixed-position elements are a special case. They are static with respect 397 // to the viewport, which is not represented by any RenderObject, and their 398 // containingBlock() method returns the root HTML element (while its true 399 // containingBlock should really be the viewport). The real measure for a 400 // non-transformed fixed-position element is as follows: any fixed position 401 // element, A, scrolls with respect an element, B, if and only if B is not 402 // fixed position. 403 // 404 // Unfortunately, it gets a bit more complicated - a fixed-position element 405 // which has a transform acts exactly as an absolute-position element 406 // (including having a real, non-viewport containing block). 407 // 408 // Below, a "root" fixed position element is defined to be one whose 409 // containing block is the root. These root-fixed-position elements are 410 // the only ones that need this special case code - other fixed position 411 // elements, as well as all absolute, relative, and static elements use the 412 // logic below. 413 const bool isRootFixedPos = position == FixedPosition && containingBlock->enclosingLayer() == rootLayer; 414 const bool otherIsRootFixedPos = otherPosition == FixedPosition && otherContainingBlock->enclosingLayer() == rootLayer; 415 416 if (isRootFixedPos && otherIsRootFixedPos) 417 return false; 418 if (isRootFixedPos || otherIsRootFixedPos) 419 return true; 420 421 if (containingBlock == otherContainingBlock) 422 return false; 423 424 // Maintain a set of containing blocks between the first layer and its 425 // closest scrollable ancestor. 426 HashSet<const RenderObject*> containingBlocks; 427 while (containingBlock) { 428 if (containingBlock->enclosingLayer()->scrollsOverflow()) 429 break; 430 containingBlocks.add(containingBlock); 431 containingBlock = containingBlock->containingBlock(); 432 } 433 434 // Do the same for the 2nd layer, but if we find a common containing block, 435 // it means both layers are contained within a single non-scrolling subtree. 436 // Hence, they will not scroll with respect to each other. 437 while (otherContainingBlock) { 438 if (containingBlocks.contains(otherContainingBlock)) 439 return false; 440 if (otherContainingBlock->enclosingLayer()->scrollsOverflow()) 441 break; 442 otherContainingBlock = otherContainingBlock->containingBlock(); 443 } 444 445 return true; 446 } 447 448 void RenderLayer::updateLayerPositionsAfterDocumentScroll() 449 { 450 ASSERT(this == renderer()->view()->layer()); 451 452 RenderGeometryMap geometryMap(UseTransforms); 453 updateLayerPositionsAfterScroll(&geometryMap); 454 } 455 456 void RenderLayer::updateLayerPositionsAfterOverflowScroll() 457 { 458 RenderGeometryMap geometryMap(UseTransforms); 459 RenderView* view = renderer()->view(); 460 if (this != view->layer()) 461 geometryMap.pushMappingsToAncestor(parent(), 0); 462 463 // FIXME: why is it OK to not check the ancestors of this layer in order to 464 // initialize the HasSeenViewportConstrainedAncestor and HasSeenAncestorWithOverflowClip flags? 465 updateLayerPositionsAfterScroll(&geometryMap, IsOverflowScroll); 466 } 467 468 void RenderLayer::updateLayerPositionsAfterScroll(RenderGeometryMap* geometryMap, UpdateLayerPositionsAfterScrollFlags flags) 469 { 470 // FIXME: This shouldn't be needed, but there are some corner cases where 471 // these flags are still dirty. Update so that the check below is valid. 472 updateDescendantDependentFlags(); 473 474 // If we have no visible content and no visible descendants, there is no point recomputing 475 // our rectangles as they will be empty. If our visibility changes, we are expected to 476 // recompute all our positions anyway. 477 if (subtreeIsInvisible()) 478 return; 479 480 bool positionChanged = updateLayerPosition(); 481 if (positionChanged) 482 flags |= HasChangedAncestor; 483 484 if (geometryMap) 485 geometryMap->pushMappingsToAncestor(this, parent()); 486 487 if (flags & HasChangedAncestor || flags & HasSeenViewportConstrainedAncestor || flags & IsOverflowScroll) 488 m_clipper.clearClipRects(); 489 490 if (renderer()->style()->hasViewportConstrainedPosition()) 491 flags |= HasSeenViewportConstrainedAncestor; 492 493 if (renderer()->hasOverflowClip()) 494 flags |= HasSeenAncestorWithOverflowClip; 495 496 if (flags & HasSeenViewportConstrainedAncestor 497 || (flags & IsOverflowScroll && flags & HasSeenAncestorWithOverflowClip && !m_canSkipRepaintRectsUpdateOnScroll)) { 498 // FIXME: We could track the repaint container as we walk down the tree. 499 repainter().computeRepaintRects(renderer()->containerForRepaint(), geometryMap); 500 } else { 501 // Check that RenderLayerRepainter's cached rects are correct. 502 // FIXME: re-enable these assertions when the issue with table cells is resolved: https://bugs.webkit.org/show_bug.cgi?id=103432 503 // ASSERT(repainter().m_repaintRect == renderer()->clippedOverflowRectForRepaint(renderer()->containerForRepaint())); 504 // ASSERT(repainter().m_outlineBox == renderer()->outlineBoundsForRepaint(renderer()->containerForRepaint(), geometryMap)); 505 } 506 507 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 508 child->updateLayerPositionsAfterScroll(geometryMap, flags); 509 510 // We don't update our reflection as scrolling is a translation which does not change the size() 511 // of an object, thus RenderReplica will still repaint itself properly as the layer position was 512 // updated above. 513 514 if (geometryMap) 515 geometryMap->popMappingsToAncestor(parent()); 516 } 517 518 bool RenderLayer::hasBlendMode() const 519 { 520 return RuntimeEnabledFeatures::cssCompositingEnabled() && renderer()->hasBlendMode(); 521 } 522 523 void RenderLayer::updateBlendMode() 524 { 525 if (!RuntimeEnabledFeatures::cssCompositingEnabled()) 526 return; 527 528 bool hadBlendMode = m_blendMode != blink::WebBlendModeNormal; 529 blink::WebBlendMode newBlendMode = renderer()->style()->blendMode(); 530 if (newBlendMode != m_blendMode) { 531 m_blendMode = newBlendMode; 532 533 // Only update the flag if a blend mode is set or unset. 534 if (parent() && (!hadBlendMode || !hasBlendMode())) 535 parent()->dirtyAncestorChainBlendedDescendantStatus(); 536 537 if (hasCompositedLayerMapping()) 538 compositedLayerMapping()->setBlendMode(newBlendMode); 539 } 540 } 541 542 void RenderLayer::updateTransform() 543 { 544 // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set, 545 // so check style too. 546 bool hasTransform = renderer()->hasTransform() && renderer()->style()->hasTransform(); 547 bool had3DTransform = has3DTransform(); 548 549 bool hadTransform = m_transform; 550 if (hasTransform != hadTransform) { 551 if (hasTransform) 552 m_transform = adoptPtr(new TransformationMatrix); 553 else 554 m_transform.clear(); 555 556 // Layers with transforms act as clip rects roots, so clear the cached clip rects here. 557 m_clipper.clearClipRectsIncludingDescendants(); 558 } 559 560 if (hasTransform) { 561 RenderBox* box = renderBox(); 562 ASSERT(box); 563 m_transform->makeIdentity(); 564 box->style()->applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin); 565 makeMatrixRenderable(*m_transform, canRender3DTransforms()); 566 } 567 568 if (had3DTransform != has3DTransform()) 569 dirty3DTransformedDescendantStatus(); 570 } 571 572 TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const 573 { 574 if (!m_transform) 575 return TransformationMatrix(); 576 577 // FIXME: handle this under web-animations 578 if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled() && renderer()->style()->isRunningAcceleratedAnimation()) { 579 TransformationMatrix currTransform; 580 RefPtr<RenderStyle> style = renderer()->animation().getAnimatedStyleForRenderer(renderer()); 581 style->applyTransform(currTransform, renderBox()->pixelSnappedBorderBoxRect().size(), applyOrigin); 582 makeMatrixRenderable(currTransform, canRender3DTransforms()); 583 return currTransform; 584 } 585 586 // m_transform includes transform-origin, so we need to recompute the transform here. 587 if (applyOrigin == RenderStyle::ExcludeTransformOrigin) { 588 RenderBox* box = renderBox(); 589 TransformationMatrix currTransform; 590 box->style()->applyTransform(currTransform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin); 591 makeMatrixRenderable(currTransform, canRender3DTransforms()); 592 return currTransform; 593 } 594 595 return *m_transform; 596 } 597 598 TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const 599 { 600 if (!m_transform) 601 return TransformationMatrix(); 602 603 if (paintBehavior & PaintBehaviorFlattenCompositingLayers) { 604 TransformationMatrix matrix = *m_transform; 605 makeMatrixRenderable(matrix, false /* flatten 3d */); 606 return matrix; 607 } 608 609 return *m_transform; 610 } 611 612 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer) 613 { 614 RenderView* view = renderer->view(); 615 RenderLayerModelObject* prevBlock = renderer; 616 RenderBlock* containingBlock; 617 for (containingBlock = renderer->containingBlock(); 618 containingBlock && containingBlock != view && containingBlock != ancestorColumnsRenderer; 619 containingBlock = containingBlock->containingBlock()) 620 prevBlock = containingBlock; 621 622 // If the columns block wasn't in our containing block chain, then we aren't paginated by it. 623 if (containingBlock != ancestorColumnsRenderer) 624 return false; 625 626 // If the previous block is absolutely positioned, then we can't be paginated by the columns block. 627 if (prevBlock->isOutOfFlowPositioned()) 628 return false; 629 630 // Otherwise we are paginated by the columns block. 631 return true; 632 } 633 634 bool RenderLayer::useRegionBasedColumns() const 635 { 636 const Settings* settings = renderer()->document().settings(); 637 return settings && settings->regionBasedColumnsEnabled(); 638 } 639 640 void RenderLayer::updatePagination() 641 { 642 m_isPaginated = false; 643 m_enclosingPaginationLayer = 0; 644 645 if (hasCompositedLayerMapping() || !parent()) 646 return; // FIXME: We will have to deal with paginated compositing layers someday. 647 // FIXME: For now the RenderView can't be paginated. Eventually printing will move to a model where it is though. 648 649 // The main difference between the paginated booleans for the old column code and the new column code 650 // is that each paginated layer has to paint on its own with the new code. There is no 651 // recurring into child layers. This means that the m_isPaginated bits for the new column code can't just be set on 652 // "roots" that get split and paint all their descendants. Instead each layer has to be checked individually and 653 // genuinely know if it is going to have to split itself up when painting only its contents (and not any other descendant 654 // layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back 655 // to that layer easily. 656 bool regionBasedColumnsUsed = useRegionBasedColumns(); 657 if (regionBasedColumnsUsed && renderer()->isInFlowRenderFlowThread()) { 658 m_enclosingPaginationLayer = this; 659 return; 660 } 661 662 if (m_stackingNode->isNormalFlowOnly()) { 663 if (regionBasedColumnsUsed) { 664 // Content inside a transform is not considered to be paginated, since we simply 665 // paint the transform multiple times in each column, so we don't have to use 666 // fragments for the transformed content. 667 m_enclosingPaginationLayer = parent()->enclosingPaginationLayer(); 668 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform()) 669 m_enclosingPaginationLayer = 0; 670 } else 671 m_isPaginated = parent()->renderer()->hasColumns(); 672 return; 673 } 674 675 // For the new columns code, we want to walk up our containing block chain looking for an enclosing layer. Once 676 // we find one, then we just check its pagination status. 677 if (regionBasedColumnsUsed) { 678 RenderView* view = renderer()->view(); 679 RenderBlock* containingBlock; 680 for (containingBlock = renderer()->containingBlock(); 681 containingBlock && containingBlock != view; 682 containingBlock = containingBlock->containingBlock()) { 683 if (containingBlock->hasLayer()) { 684 // Content inside a transform is not considered to be paginated, since we simply 685 // paint the transform multiple times in each column, so we don't have to use 686 // fragments for the transformed content. 687 m_enclosingPaginationLayer = containingBlock->layer()->enclosingPaginationLayer(); 688 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform()) 689 m_enclosingPaginationLayer = 0; 690 return; 691 } 692 } 693 return; 694 } 695 696 // If we're not normal flow, then we need to look for a multi-column object between us and our stacking container. 697 RenderLayerStackingNode* ancestorStackingContainerNode = m_stackingNode->ancestorStackingContainerNode(); 698 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) { 699 if (curr->renderer()->hasColumns()) { 700 m_isPaginated = checkContainingBlockChainForPagination(renderer(), curr->renderBox()); 701 return; 702 } 703 if (curr->stackingNode() == ancestorStackingContainerNode) 704 return; 705 } 706 } 707 708 void RenderLayer::setHasVisibleContent() 709 { 710 if (m_hasVisibleContent && !m_visibleContentStatusDirty) { 711 ASSERT(!parent() || parent()->hasVisibleDescendant()); 712 return; 713 } 714 715 m_visibleContentStatusDirty = false; 716 m_hasVisibleContent = true; 717 repainter().computeRepaintRects(renderer()->containerForRepaint()); 718 if (!m_stackingNode->isNormalFlowOnly()) { 719 // We don't collect invisible layers in z-order lists if we are not in compositing mode. 720 // As we became visible, we need to dirty our stacking containers ancestors to be properly 721 // collected. FIXME: When compositing, we could skip this dirtying phase. 722 for (RenderLayerStackingNode* sc = m_stackingNode->ancestorStackingContainerNode(); sc; sc = sc->ancestorStackingContainerNode()) { 723 sc->dirtyZOrderLists(); 724 if (sc->layer()->hasVisibleContent()) 725 break; 726 } 727 } 728 729 if (parent()) 730 parent()->setAncestorChainHasVisibleDescendant(); 731 } 732 733 void RenderLayer::dirtyVisibleContentStatus() 734 { 735 m_visibleContentStatusDirty = true; 736 if (parent()) 737 parent()->dirtyAncestorChainVisibleDescendantStatus(); 738 } 739 740 void RenderLayer::dirtyAncestorChainVisibleDescendantStatus() 741 { 742 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 743 if (layer->m_visibleDescendantStatusDirty) 744 break; 745 746 layer->m_visibleDescendantStatusDirty = true; 747 } 748 } 749 750 void RenderLayer::setAncestorChainHasVisibleDescendant() 751 { 752 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 753 if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendant()) 754 break; 755 756 layer->m_hasVisibleDescendant = true; 757 layer->m_visibleDescendantStatusDirty = false; 758 } 759 } 760 761 void RenderLayer::dirtyAncestorChainBlendedDescendantStatus() 762 { 763 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 764 if (layer->m_childLayerHasBlendModeStatusDirty) 765 break; 766 767 layer->m_childLayerHasBlendModeStatusDirty = true; 768 769 if (layer->stackingNode()->isStackingContext()) 770 break; 771 } 772 } 773 774 void RenderLayer::setAncestorChainBlendedDescendant() 775 { 776 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 777 if (!layer->m_childLayerHasBlendModeStatusDirty && layer->childLayerHasBlendMode()) 778 break; 779 780 layer->m_childLayerHasBlendMode = true; 781 layer->m_childLayerHasBlendModeStatusDirty = false; 782 783 if (layer->stackingNode()->isStackingContext()) 784 break; 785 } 786 } 787 788 void RenderLayer::updateHasUnclippedDescendant() 789 { 790 TRACE_EVENT0("blink_rendering", "RenderLayer::updateHasUnclippedDescendant"); 791 ASSERT(renderer()->isOutOfFlowPositioned()); 792 if (!m_hasVisibleContent && !m_hasVisibleDescendant) 793 return; 794 795 FrameView* frameView = renderer()->view()->frameView(); 796 if (!frameView) 797 return; 798 799 const RenderObject* containingBlock = renderer()->containingBlock(); 800 setIsUnclippedDescendant(false); 801 for (RenderLayer* ancestor = parent(); ancestor && ancestor->renderer() != containingBlock; ancestor = ancestor->parent()) { 802 // TODO(vollick): This isn't quite right. Whenever ancestor is composited and clips 803 // overflow, we're technically unclipped. However, this will currently cause a huge 804 // number of layers to report that they are unclipped. Eventually, when we've formally 805 // separated the clipping, transform, opacity, and stacking trees here and in the 806 // compositor, we will be able to relax this restriction without it being prohibitively 807 // expensive (currently, we have to do a lot of work in the compositor to honor a 808 // clip child/parent relationship). 809 if (ancestor->scrollsOverflow()) 810 setIsUnclippedDescendant(true); 811 ancestor->setHasUnclippedDescendant(true); 812 } 813 } 814 815 // FIXME: this is quite brute-force. We could be more efficient if we were to 816 // track state and update it as appropriate as changes are made in the RenderObject tree. 817 void RenderLayer::updateHasVisibleNonLayerContent() 818 { 819 TRACE_EVENT0("blink_rendering", "RenderLayer::updateHasVisibleNonLayerContent"); 820 m_hasVisibleNonLayerContent = false; 821 for (RenderObject* r = renderer()->firstChild(); r; r = r->nextSibling()) { 822 if (!r->hasLayer()) { 823 m_hasVisibleNonLayerContent = true; 824 break; 825 } 826 } 827 } 828 829 static bool subtreeContainsOutOfFlowPositionedLayer(const RenderLayer* subtreeRoot) 830 { 831 return (subtreeRoot->renderer() && subtreeRoot->renderer()->isOutOfFlowPositioned()) || subtreeRoot->hasOutOfFlowPositionedDescendant(); 832 } 833 834 void RenderLayer::updateDescendantDependentFlags() 835 { 836 if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty) { 837 m_hasVisibleDescendant = false; 838 m_hasSelfPaintingLayerDescendant = false; 839 m_hasOutOfFlowPositionedDescendant = false; 840 841 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { 842 child->updateDescendantDependentFlags(); 843 844 bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_hasVisibleDescendant; 845 bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant(); 846 bool hasOutOfFlowPositionedDescendant = subtreeContainsOutOfFlowPositionedLayer(child); 847 848 m_hasVisibleDescendant |= hasVisibleDescendant; 849 m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant; 850 m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescendant; 851 852 if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && hasOutOfFlowPositionedDescendant) 853 break; 854 } 855 856 m_visibleDescendantStatusDirty = false; 857 m_hasSelfPaintingLayerDescendantDirty = false; 858 m_hasOutOfFlowPositionedDescendantDirty = false; 859 } 860 861 if (m_childLayerHasBlendModeStatusDirty) { 862 m_childLayerHasBlendMode = false; 863 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { 864 if (!child->stackingNode()->isStackingContext()) 865 child->updateDescendantDependentFlags(); 866 867 bool childLayerHasBlendMode = child->paintsWithBlendMode() || (child->m_childLayerHasBlendMode && !child->stackingNode()->isStackingContext()); 868 m_childLayerHasBlendMode |= childLayerHasBlendMode; 869 870 if (m_childLayerHasBlendMode) 871 break; 872 } 873 m_childLayerHasBlendModeStatusDirty = false; 874 } 875 876 if (m_visibleContentStatusDirty) { 877 if (renderer()->style()->visibility() == VISIBLE) 878 m_hasVisibleContent = true; 879 else { 880 // layer may be hidden but still have some visible content, check for this 881 m_hasVisibleContent = false; 882 RenderObject* r = renderer()->firstChild(); 883 while (r) { 884 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) { 885 m_hasVisibleContent = true; 886 break; 887 } 888 if (r->firstChild() && !r->hasLayer()) 889 r = r->firstChild(); 890 else if (r->nextSibling()) 891 r = r->nextSibling(); 892 else { 893 do { 894 r = r->parent(); 895 if (r == renderer()) 896 r = 0; 897 } while (r && !r->nextSibling()); 898 if (r) 899 r = r->nextSibling(); 900 } 901 } 902 } 903 m_visibleContentStatusDirty = false; 904 } 905 } 906 907 void RenderLayer::dirty3DTransformedDescendantStatus() 908 { 909 RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContainerNode(); 910 if (!stackingNode) 911 return; 912 913 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true; 914 915 // This propagates up through preserve-3d hierarchies to the enclosing flattening layer. 916 // Note that preserves3D() creates stacking context, so we can just run up the stacking containers. 917 while (stackingNode && stackingNode->layer()->preserves3D()) { 918 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true; 919 stackingNode = stackingNode->ancestorStackingContainerNode(); 920 } 921 } 922 923 // Return true if this layer or any preserve-3d descendants have 3d. 924 bool RenderLayer::update3DTransformedDescendantStatus() 925 { 926 if (m_3DTransformedDescendantStatusDirty) { 927 m_has3DTransformedDescendant = false; 928 929 m_stackingNode->updateZOrderLists(); 930 931 // Transformed or preserve-3d descendants can only be in the z-order lists, not 932 // in the normal flow list, so we only need to check those. 933 RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), PositiveZOrderChildren | NegativeZOrderChildren); 934 while (RenderLayerStackingNode* node = iterator.next()) 935 m_has3DTransformedDescendant |= node->layer()->update3DTransformedDescendantStatus(); 936 937 m_3DTransformedDescendantStatusDirty = false; 938 } 939 940 // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs 941 // the m_has3DTransformedDescendant set. 942 if (preserves3D()) 943 return has3DTransform() || m_has3DTransformedDescendant; 944 945 return has3DTransform(); 946 } 947 948 bool RenderLayer::updateLayerPosition() 949 { 950 LayoutPoint localPoint; 951 LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done. 952 if (renderer()->isInline() && renderer()->isRenderInline()) { 953 RenderInline* inlineFlow = toRenderInline(renderer()); 954 IntRect lineBox = inlineFlow->linesBoundingBox(); 955 setSize(lineBox.size()); 956 inlineBoundingBoxOffset = toSize(lineBox.location()); 957 localPoint += inlineBoundingBoxOffset; 958 } else if (RenderBox* box = renderBox()) { 959 // FIXME: Is snapping the size really needed here for the RenderBox case? 960 setSize(pixelSnappedIntSize(box->size(), box->location())); 961 localPoint += box->topLeftLocationOffset(); 962 } 963 964 if (!renderer()->isOutOfFlowPositioned() && renderer()->parent()) { 965 // We must adjust our position by walking up the render tree looking for the 966 // nearest enclosing object with a layer. 967 RenderObject* curr = renderer()->parent(); 968 while (curr && !curr->hasLayer()) { 969 if (curr->isBox() && !curr->isTableRow()) { 970 // Rows and cells share the same coordinate space (that of the section). 971 // Omit them when computing our xpos/ypos. 972 localPoint += toRenderBox(curr)->topLeftLocationOffset(); 973 } 974 curr = curr->parent(); 975 } 976 if (curr->isBox() && curr->isTableRow()) { 977 // Put ourselves into the row coordinate space. 978 localPoint -= toRenderBox(curr)->topLeftLocationOffset(); 979 } 980 } 981 982 // Subtract our parent's scroll offset. 983 if (renderer()->isOutOfFlowPositioned() && enclosingPositionedAncestor()) { 984 RenderLayer* positionedParent = enclosingPositionedAncestor(); 985 986 // For positioned layers, we subtract out the enclosing positioned layer's scroll offset. 987 if (positionedParent->renderer()->hasOverflowClip()) { 988 LayoutSize offset = positionedParent->renderBox()->scrolledContentOffset(); 989 localPoint -= offset; 990 } 991 992 if (renderer()->isOutOfFlowPositioned() && positionedParent->renderer()->isInFlowPositioned() && positionedParent->renderer()->isRenderInline()) { 993 LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(toRenderBox(renderer())); 994 localPoint += offset; 995 } 996 } else if (parent()) { 997 if (hasCompositedLayerMapping()) { 998 // FIXME: Composited layers ignore pagination, so about the best we can do is make sure they're offset into the appropriate column. 999 // They won't split across columns properly. 1000 LayoutSize columnOffset; 1001 if (!parent()->renderer()->hasColumns() && parent()->renderer()->isRoot() && renderer()->view()->hasColumns()) 1002 renderer()->view()->adjustForColumns(columnOffset, localPoint); 1003 else 1004 parent()->renderer()->adjustForColumns(columnOffset, localPoint); 1005 1006 localPoint += columnOffset; 1007 } 1008 1009 if (parent()->renderer()->hasOverflowClip()) { 1010 IntSize scrollOffset = parent()->renderBox()->scrolledContentOffset(); 1011 localPoint -= scrollOffset; 1012 } 1013 } 1014 1015 bool positionOrOffsetChanged = false; 1016 if (renderer()->isInFlowPositioned()) { 1017 LayoutSize newOffset = toRenderBoxModelObject(renderer())->offsetForInFlowPosition(); 1018 positionOrOffsetChanged = newOffset != m_offsetForInFlowPosition; 1019 m_offsetForInFlowPosition = newOffset; 1020 localPoint.move(m_offsetForInFlowPosition); 1021 } else { 1022 m_offsetForInFlowPosition = LayoutSize(); 1023 } 1024 1025 // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers. 1026 localPoint -= inlineBoundingBoxOffset; 1027 1028 positionOrOffsetChanged |= location() != localPoint; 1029 setLocation(localPoint); 1030 return positionOrOffsetChanged; 1031 } 1032 1033 TransformationMatrix RenderLayer::perspectiveTransform() const 1034 { 1035 if (!renderer()->hasTransform()) 1036 return TransformationMatrix(); 1037 1038 RenderStyle* style = renderer()->style(); 1039 if (!style->hasPerspective()) 1040 return TransformationMatrix(); 1041 1042 // Maybe fetch the perspective from the backing? 1043 const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect(); 1044 const float boxWidth = borderBox.width(); 1045 const float boxHeight = borderBox.height(); 1046 1047 float perspectiveOriginX = floatValueForLength(style->perspectiveOriginX(), boxWidth); 1048 float perspectiveOriginY = floatValueForLength(style->perspectiveOriginY(), boxHeight); 1049 1050 // A perspective origin of 0,0 makes the vanishing point in the center of the element. 1051 // We want it to be in the top-left, so subtract half the height and width. 1052 perspectiveOriginX -= boxWidth / 2.0f; 1053 perspectiveOriginY -= boxHeight / 2.0f; 1054 1055 TransformationMatrix t; 1056 t.translate(perspectiveOriginX, perspectiveOriginY); 1057 t.applyPerspective(style->perspective()); 1058 t.translate(-perspectiveOriginX, -perspectiveOriginY); 1059 1060 return t; 1061 } 1062 1063 FloatPoint RenderLayer::perspectiveOrigin() const 1064 { 1065 if (!renderer()->hasTransform()) 1066 return FloatPoint(); 1067 1068 const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect(); 1069 RenderStyle* style = renderer()->style(); 1070 1071 return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox.width()), 1072 floatValueForLength(style->perspectiveOriginY(), borderBox.height())); 1073 } 1074 1075 static inline bool isFixedPositionedContainer(RenderLayer* layer) 1076 { 1077 return layer->isRootLayer() || layer->hasTransform(); 1078 } 1079 1080 RenderLayer* RenderLayer::enclosingPositionedAncestor() const 1081 { 1082 RenderLayer* curr = parent(); 1083 while (curr && !curr->isPositionedContainer()) 1084 curr = curr->parent(); 1085 1086 return curr; 1087 } 1088 1089 RenderLayer* RenderLayer::enclosingScrollableLayer() const 1090 { 1091 if (RenderBox* enclosingScrollableBox = renderer()->enclosingScrollableBox()) 1092 return enclosingScrollableBox->layer(); 1093 1094 return 0; 1095 } 1096 1097 RenderLayer* RenderLayer::enclosingTransformedAncestor() const 1098 { 1099 RenderLayer* curr = parent(); 1100 while (curr && !curr->isRootLayer() && !curr->transform()) 1101 curr = curr->parent(); 1102 1103 return curr; 1104 } 1105 1106 static inline const RenderLayer* compositingContainer(const RenderLayer* layer) 1107 { 1108 return layer->stackingNode()->isNormalFlowOnly() ? layer->parent() : (layer->stackingNode()->ancestorStackingContainerNode() ? layer->stackingNode()->ancestorStackingContainerNode()->layer() : 0); 1109 } 1110 1111 // FIXME: having two different functions named enclosingCompositingLayer and enclosingCompositingLayerForRepaint 1112 // is error-prone and misleading for reading code that uses these functions - especially compounded with 1113 // the includeSelf option. It is very likely that we don't even want either of these functions; A layer 1114 // should be told explicitly which GraphicsLayer is the repaintContainer for a RenderLayer, and 1115 // any other use cases should probably have an API between the non-compositing and compositing sides of code. 1116 RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const 1117 { 1118 if (includeSelf && compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking) 1119 return const_cast<RenderLayer*>(this); 1120 1121 for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) { 1122 if (curr->compositingState() != NotComposited && curr->compositingState() != PaintsIntoGroupedBacking) 1123 return const_cast<RenderLayer*>(curr); 1124 } 1125 1126 return 0; 1127 } 1128 1129 RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(bool includeSelf) const 1130 { 1131 if (includeSelf && (compositingState() == PaintsIntoOwnBacking || compositingState() == PaintsIntoGroupedBacking)) 1132 return const_cast<RenderLayer*>(this); 1133 1134 for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) { 1135 if (curr->compositingState() == PaintsIntoOwnBacking || curr->compositingState() == PaintsIntoGroupedBacking) 1136 return const_cast<RenderLayer*>(curr); 1137 } 1138 1139 return 0; 1140 } 1141 1142 RenderLayer* RenderLayer::ancestorCompositedScrollingLayer() const 1143 { 1144 if (!acceleratedCompositingForOverflowScrollEnabled()) 1145 return 0; 1146 1147 RenderObject* containingBlock = renderer()->containingBlock(); 1148 if (!containingBlock) 1149 return 0; 1150 1151 for (RenderLayer* ancestorLayer = containingBlock->enclosingLayer(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) { 1152 if (ancestorLayer->needsCompositedScrolling()) 1153 return ancestorLayer; 1154 } 1155 1156 return 0; 1157 } 1158 1159 RenderLayer* RenderLayer::ancestorScrollingLayer() const 1160 { 1161 RenderObject* containingBlock = renderer()->containingBlock(); 1162 if (!containingBlock) 1163 return 0; 1164 1165 for (RenderLayer* ancestorLayer = containingBlock->enclosingLayer(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) { 1166 if (ancestorLayer->scrollsOverflow()) 1167 return ancestorLayer; 1168 } 1169 1170 return 0; 1171 } 1172 1173 RenderLayer* RenderLayer::enclosingFilterLayer(bool includeSelf) const 1174 { 1175 const RenderLayer* curr = includeSelf ? this : parent(); 1176 for (; curr; curr = curr->parent()) { 1177 if (curr->requiresFullLayerImageForFilters()) 1178 return const_cast<RenderLayer*>(curr); 1179 } 1180 1181 return 0; 1182 } 1183 1184 bool RenderLayer::hasAncestorWithFilterOutsets() const 1185 { 1186 for (const RenderLayer* curr = this; curr; curr = curr->parent()) { 1187 RenderLayerModelObject* renderer = curr->renderer(); 1188 if (renderer->style()->hasFilterOutsets()) 1189 return true; 1190 } 1191 return false; 1192 } 1193 1194 RenderLayer* RenderLayer::clippingRootForPainting() const 1195 { 1196 if (hasCompositedLayerMapping()) 1197 return const_cast<RenderLayer*>(this); 1198 1199 const RenderLayer* current = this; 1200 while (current) { 1201 if (current->isRootLayer()) 1202 return const_cast<RenderLayer*>(current); 1203 1204 current = compositingContainer(current); 1205 ASSERT(current); 1206 if (current->transform() 1207 || (current->compositingState() == PaintsIntoOwnBacking) 1208 ) 1209 return const_cast<RenderLayer*>(current); 1210 } 1211 1212 ASSERT_NOT_REACHED(); 1213 return 0; 1214 } 1215 1216 bool RenderLayer::cannotBlitToWindow() const 1217 { 1218 if (isTransparent() || m_reflectionInfo || hasTransform()) 1219 return true; 1220 if (!parent()) 1221 return false; 1222 return parent()->cannotBlitToWindow(); 1223 } 1224 1225 bool RenderLayer::isTransparent() const 1226 { 1227 if (renderer()->node() && renderer()->node()->isSVGElement()) 1228 return false; 1229 1230 return renderer()->isTransparent() || renderer()->hasMask(); 1231 } 1232 1233 RenderLayer* RenderLayer::transparentPaintingAncestor() 1234 { 1235 if (hasCompositedLayerMapping()) 1236 return 0; 1237 1238 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) { 1239 if (curr->hasCompositedLayerMapping()) 1240 return 0; 1241 if (curr->isTransparent()) 1242 return curr; 1243 } 1244 return 0; 1245 } 1246 1247 enum TransparencyClipBoxBehavior { 1248 PaintingTransparencyClipBox, 1249 HitTestingTransparencyClipBox 1250 }; 1251 1252 enum TransparencyClipBoxMode { 1253 DescendantsOfTransparencyClipBox, 1254 RootOfTransparencyClipBox 1255 }; 1256 1257 static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, PaintBehavior = 0); 1258 1259 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer, 1260 TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior) 1261 { 1262 // If we have a mask, then the clip is limited to the border box area (and there is 1263 // no need to examine child layers). 1264 if (!layer->renderer()->hasMask()) { 1265 // Note: we don't have to walk z-order lists since transparent elements always establish 1266 // a stacking container. This means we can just walk the layer tree directly. 1267 for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) { 1268 if (!layer->reflectionInfo() || layer->reflectionInfo()->reflectionLayer() != curr) 1269 clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior)); 1270 } 1271 } 1272 1273 // If we have a reflection, then we need to account for that when we push the clip. Reflect our entire 1274 // current transparencyClipBox to catch all child layers. 1275 // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this 1276 // size into the parent layer. 1277 if (layer->renderer()->hasReflection()) { 1278 LayoutPoint delta; 1279 layer->convertToLayerCoords(rootLayer, delta); 1280 clipRect.move(-delta.x(), -delta.y()); 1281 clipRect.unite(layer->renderBox()->reflectedRect(clipRect)); 1282 clipRect.moveBy(delta); 1283 } 1284 } 1285 1286 static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior, 1287 TransparencyClipBoxMode transparencyMode, PaintBehavior paintBehavior) 1288 { 1289 // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the 1290 // paintDirtyRect, and that should cut down on the amount we have to paint. Still it 1291 // would be better to respect clips. 1292 1293 if (rootLayer != layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer->paintsWithTransform(paintBehavior)) 1294 || (transparencyBehavior == HitTestingTransparencyClipBox && layer->hasTransform()))) { 1295 // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass 1296 // the transformed layer and all of its children. 1297 const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer->enclosingPaginationLayer() : 0; 1298 const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer; 1299 LayoutPoint delta; 1300 layer->convertToLayerCoords(rootLayerForTransform, delta); 1301 1302 TransformationMatrix transform; 1303 transform.translate(delta.x(), delta.y()); 1304 transform = transform * *layer->transform(); 1305 1306 // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always 1307 // paints unfragmented. 1308 LayoutRect clipRect = layer->boundingBox(layer); 1309 expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, paintBehavior); 1310 layer->renderer()->style()->filterOutsets().expandRect(clipRect); 1311 LayoutRect result = transform.mapRect(clipRect); 1312 if (!paginationLayer) 1313 return result; 1314 1315 // We have to break up the transformed extent across our columns. 1316 // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to 1317 // get our true bounding box. 1318 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer()); 1319 result = enclosingFlowThread->fragmentsBoundingBox(result); 1320 1321 LayoutPoint rootLayerDelta; 1322 paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta); 1323 result.moveBy(rootLayerDelta); 1324 return result; 1325 } 1326 1327 LayoutRect clipRect = layer->boundingBox(rootLayer, RenderLayer::UseFragmentBoxes); 1328 expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior); 1329 layer->renderer()->style()->filterOutsets().expandRect(clipRect); 1330 return clipRect; 1331 } 1332 1333 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior) 1334 { 1335 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect); 1336 } 1337 1338 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior) 1339 { 1340 bool createTransparencyLayerForBlendMode = m_stackingNode->isStackingContext() && m_childLayerHasBlendMode; 1341 if (context->paintingDisabled() || ((paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency)) 1342 return; 1343 1344 RenderLayer* ancestor = transparentPaintingAncestor(); 1345 if (ancestor) 1346 ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior); 1347 1348 if (paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) { 1349 m_usedTransparency = true; 1350 context->save(); 1351 LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBehavior); 1352 context->clip(clipRect); 1353 if (paintsWithBlendMode()) 1354 context->setCompositeOperation(context->compositeOperation(), m_blendMode); 1355 1356 context->beginTransparencyLayer(renderer()->opacity()); 1357 #ifdef REVEAL_TRANSPARENCY_LAYERS 1358 context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f)); 1359 context->fillRect(clipRect); 1360 #endif 1361 } 1362 } 1363 1364 void* RenderLayer::operator new(size_t sz) 1365 { 1366 return partitionAlloc(Partitions::getRenderingPartition(), sz); 1367 } 1368 1369 void RenderLayer::operator delete(void* ptr) 1370 { 1371 partitionFree(ptr); 1372 } 1373 1374 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild) 1375 { 1376 RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild(); 1377 if (prevSibling) { 1378 child->setPreviousSibling(prevSibling); 1379 prevSibling->setNextSibling(child); 1380 ASSERT(prevSibling != child); 1381 } else 1382 setFirstChild(child); 1383 1384 if (beforeChild) { 1385 beforeChild->setPreviousSibling(child); 1386 child->setNextSibling(beforeChild); 1387 ASSERT(beforeChild != child); 1388 } else 1389 setLastChild(child); 1390 1391 child->setParent(this); 1392 1393 if (child->stackingNode()->isNormalFlowOnly()) 1394 m_stackingNode->dirtyNormalFlowList(); 1395 1396 if (!child->stackingNode()->isNormalFlowOnly() || child->firstChild()) { 1397 // Dirty the z-order list in which we are contained. The ancestorStackingContainerNode() can be null in the 1398 // case where we're building up generated content layers. This is ok, since the lists will start 1399 // off dirty in that case anyway. 1400 child->stackingNode()->dirtyStackingContainerZOrderLists(); 1401 } 1402 1403 child->updateDescendantDependentFlags(); 1404 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) 1405 setAncestorChainHasVisibleDescendant(); 1406 1407 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) 1408 setAncestorChainHasSelfPaintingLayerDescendant(); 1409 1410 if (child->paintsWithBlendMode() || child->childLayerHasBlendMode()) 1411 setAncestorChainBlendedDescendant(); 1412 1413 if (subtreeContainsOutOfFlowPositionedLayer(child)) { 1414 // Now that the out of flow positioned descendant is in the tree, we 1415 // need to tell the compositor to reevaluate the compositing 1416 // requirements since we may be able to mark more layers as having 1417 // an 'unclipped' descendant. 1418 compositor()->setNeedsUpdateCompositingRequirementsState(); 1419 setAncestorChainHasOutOfFlowPositionedDescendant(); 1420 } 1421 1422 // When we first dirty a layer, we will also dirty all the siblings in that 1423 // layer's stacking context. We need to manually do it here as well, in case 1424 // we're adding this layer after the stacking context has already been 1425 // updated. 1426 child->stackingNode()->setDescendantsAreContiguousInStackingOrderDirty(true); 1427 compositor()->layerWasAdded(this, child); 1428 } 1429 1430 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild) 1431 { 1432 if (!renderer()->documentBeingDestroyed()) 1433 compositor()->layerWillBeRemoved(this, oldChild); 1434 1435 // remove the child 1436 if (oldChild->previousSibling()) 1437 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); 1438 if (oldChild->nextSibling()) 1439 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()); 1440 1441 if (m_first == oldChild) 1442 m_first = oldChild->nextSibling(); 1443 if (m_last == oldChild) 1444 m_last = oldChild->previousSibling(); 1445 1446 if (oldChild->stackingNode()->isNormalFlowOnly()) 1447 m_stackingNode->dirtyNormalFlowList(); 1448 if (!oldChild->stackingNode()->isNormalFlowOnly() || oldChild->firstChild()) { 1449 // Dirty the z-order list in which we are contained. When called via the 1450 // reattachment process in removeOnlyThisLayer, the layer may already be disconnected 1451 // from the main layer tree, so we need to null-check the |stackingContainer| value. 1452 oldChild->stackingNode()->dirtyStackingContainerZOrderLists(); 1453 } 1454 1455 oldChild->setPreviousSibling(0); 1456 oldChild->setNextSibling(0); 1457 oldChild->setParent(0); 1458 1459 oldChild->updateDescendantDependentFlags(); 1460 if (subtreeContainsOutOfFlowPositionedLayer(oldChild)) { 1461 // It may now be the case that a layer no longer has an unclipped 1462 // descendant. Let the compositor know that it needs to reevaluate 1463 // its compositing requirements to check this. 1464 compositor()->setNeedsUpdateCompositingRequirementsState(); 1465 dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus(); 1466 } 1467 1468 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) 1469 dirtyAncestorChainVisibleDescendantStatus(); 1470 1471 if (oldChild->paintsWithBlendMode() || oldChild->childLayerHasBlendMode()) 1472 dirtyAncestorChainBlendedDescendantStatus(); 1473 1474 if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescendant()) 1475 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 1476 1477 return oldChild; 1478 } 1479 1480 void RenderLayer::removeOnlyThisLayer() 1481 { 1482 if (!m_parent) 1483 return; 1484 1485 compositor()->layerWillBeRemoved(m_parent, this); 1486 1487 // Dirty the clip rects. 1488 m_clipper.clearClipRectsIncludingDescendants(); 1489 1490 RenderLayer* nextSib = nextSibling(); 1491 1492 // Remove the child reflection layer before moving other child layers. 1493 // The reflection layer should not be moved to the parent. 1494 if (m_reflectionInfo) 1495 removeChild(m_reflectionInfo->reflectionLayer()); 1496 1497 // Now walk our kids and reattach them to our parent. 1498 RenderLayer* current = m_first; 1499 while (current) { 1500 RenderLayer* next = current->nextSibling(); 1501 removeChild(current); 1502 m_parent->addChild(current, nextSib); 1503 current->repainter().setRepaintStatus(NeedsFullRepaint); 1504 current->updateLayerPositions(0); // FIXME: use geometry map. 1505 current = next; 1506 } 1507 1508 // Remove us from the parent. 1509 m_parent->removeChild(this); 1510 m_renderer->destroyLayer(); 1511 } 1512 1513 void RenderLayer::insertOnlyThisLayer() 1514 { 1515 if (!m_parent && renderer()->parent()) { 1516 // We need to connect ourselves when our renderer() has a parent. 1517 // Find our enclosingLayer and add ourselves. 1518 RenderLayer* parentLayer = renderer()->parent()->enclosingLayer(); 1519 ASSERT(parentLayer); 1520 RenderLayer* beforeChild = !parentLayer->reflectionInfo() || parentLayer->reflectionInfo()->reflectionLayer() != this ? renderer()->parent()->findNextLayer(parentLayer, renderer()) : 0; 1521 parentLayer->addChild(this, beforeChild); 1522 } 1523 1524 // Remove all descendant layers from the hierarchy and add them to the new position. 1525 for (RenderObject* curr = renderer()->firstChild(); curr; curr = curr->nextSibling()) 1526 curr->moveLayers(m_parent, this); 1527 1528 // Clear out all the clip rects. 1529 m_clipper.clearClipRectsIncludingDescendants(); 1530 } 1531 1532 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation) const 1533 { 1534 LayoutPoint location = roundedLocation; 1535 convertToLayerCoords(ancestorLayer, location); 1536 roundedLocation = roundedIntPoint(location); 1537 } 1538 1539 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntRect& roundedRect) const 1540 { 1541 LayoutRect rect = roundedRect; 1542 convertToLayerCoords(ancestorLayer, rect); 1543 roundedRect = pixelSnappedIntRect(rect); 1544 } 1545 1546 // Returns the layer reached on the walk up towards the ancestor. 1547 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location) 1548 { 1549 ASSERT(ancestorLayer != layer); 1550 1551 const RenderLayerModelObject* renderer = layer->renderer(); 1552 EPosition position = renderer->style()->position(); 1553 1554 // FIXME: Special casing RenderFlowThread so much for fixed positioning here is not great. 1555 RenderFlowThread* fixedFlowThreadContainer = position == FixedPosition ? renderer->flowThreadContainingBlock() : 0; 1556 if (fixedFlowThreadContainer && !fixedFlowThreadContainer->isOutOfFlowPositioned()) 1557 fixedFlowThreadContainer = 0; 1558 1559 // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread 1560 // may need to be revisited in a future patch. 1561 // If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute, 1562 // since localToAbsolute maps the coordinates from named flow to regions coordinates and regions can be 1563 // positioned in a completely different place in the viewport (RenderView). 1564 if (position == FixedPosition && !fixedFlowThreadContainer && (!ancestorLayer || ancestorLayer == renderer->view()->layer())) { 1565 // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling 1566 // localToAbsolute() on the RenderView. 1567 FloatPoint absPos = renderer->localToAbsolute(FloatPoint(), IsFixed); 1568 location += LayoutSize(absPos.x(), absPos.y()); 1569 return ancestorLayer; 1570 } 1571 1572 // For the fixed positioned elements inside a render flow thread, we should also skip the code path below 1573 // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed 1574 // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer. 1575 if (position == FixedPosition && !fixedFlowThreadContainer) { 1576 // For a fixed layers, we need to walk up to the root to see if there's a fixed position container 1577 // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform, 1578 // so we should always find the ancestor at or before we find the fixed position container. 1579 RenderLayer* fixedPositionContainerLayer = 0; 1580 bool foundAncestor = false; 1581 for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) { 1582 if (currLayer == ancestorLayer) 1583 foundAncestor = true; 1584 1585 if (isFixedPositionedContainer(currLayer)) { 1586 fixedPositionContainerLayer = currLayer; 1587 ASSERT_UNUSED(foundAncestor, foundAncestor); 1588 break; 1589 } 1590 } 1591 1592 ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least. 1593 1594 if (fixedPositionContainerLayer != ancestorLayer) { 1595 LayoutPoint fixedContainerCoords; 1596 layer->convertToLayerCoords(fixedPositionContainerLayer, fixedContainerCoords); 1597 1598 LayoutPoint ancestorCoords; 1599 ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorCoords); 1600 1601 location += (fixedContainerCoords - ancestorCoords); 1602 } else { 1603 location += toSize(layer->location()); 1604 } 1605 return ancestorLayer; 1606 } 1607 1608 RenderLayer* parentLayer; 1609 if (position == AbsolutePosition || position == FixedPosition) { 1610 // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way. 1611 parentLayer = layer->parent(); 1612 bool foundAncestorFirst = false; 1613 while (parentLayer) { 1614 // RenderFlowThread is a positioned container, child of RenderView, positioned at (0,0). 1615 // This implies that, for out-of-flow positioned elements inside a RenderFlowThread, 1616 // we are bailing out before reaching root layer. 1617 if (parentLayer->isPositionedContainer()) 1618 break; 1619 1620 if (parentLayer == ancestorLayer) { 1621 foundAncestorFirst = true; 1622 break; 1623 } 1624 1625 parentLayer = parentLayer->parent(); 1626 } 1627 1628 // We should not reach RenderView layer past the RenderFlowThread layer for any 1629 // children of the RenderFlowThread. 1630 if (renderer->flowThreadContainingBlock() && !layer->isOutOfFlowRenderFlowThread()) 1631 ASSERT(parentLayer != renderer->view()->layer()); 1632 1633 if (foundAncestorFirst) { 1634 // Found ancestorLayer before the abs. positioned container, so compute offset of both relative 1635 // to enclosingPositionedAncestor and subtract. 1636 RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor(); 1637 1638 LayoutPoint thisCoords; 1639 layer->convertToLayerCoords(positionedAncestor, thisCoords); 1640 1641 LayoutPoint ancestorCoords; 1642 ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoords); 1643 1644 location += (thisCoords - ancestorCoords); 1645 return ancestorLayer; 1646 } 1647 } else 1648 parentLayer = layer->parent(); 1649 1650 if (!parentLayer) 1651 return 0; 1652 1653 location += toSize(layer->location()); 1654 return parentLayer; 1655 } 1656 1657 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const 1658 { 1659 if (ancestorLayer == this) 1660 return; 1661 1662 const RenderLayer* currLayer = this; 1663 while (currLayer && currLayer != ancestorLayer) 1664 currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, location); 1665 } 1666 1667 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect& rect) const 1668 { 1669 LayoutPoint delta; 1670 convertToLayerCoords(ancestorLayer, delta); 1671 rect.move(-delta.x(), -delta.y()); 1672 } 1673 1674 RenderLayer* RenderLayer::scrollParent() const 1675 { 1676 if (!compositorDrivenAcceleratedScrollingEnabled()) 1677 return 0; 1678 1679 // Normal flow elements will be parented under the main scrolling layer, so 1680 // we don't need a scroll parent/child relationship to get them to scroll. 1681 if (stackingNode()->isNormalFlowOnly()) 1682 return 0; 1683 1684 // A layer scrolls with its containing block. So to find the overflow scrolling layer 1685 // that we scroll with respect to, we must ascend the layer tree until we reach the 1686 // first overflow scrolling div at or above our containing block. I will refer to this 1687 // layer as our 'scrolling ancestor'. 1688 // 1689 // Now, if we reside in a normal flow list, then we will naturally scroll with our scrolling 1690 // ancestor, and we need not be composited. If, on the other hand, we reside in a z-order 1691 // list, and on our walk upwards to our scrolling ancestor we find no layer that is a stacking 1692 // context, then we know that in the stacking tree, we will not be in the subtree rooted at 1693 // our scrolling ancestor, and we will therefore not scroll with it. In this case, we must 1694 // be a composited layer since the compositor will need to take special measures to ensure 1695 // that we scroll with our scrolling ancestor and it cannot do this if we do not promote. 1696 RenderLayer* scrollParent = ancestorCompositedScrollingLayer(); 1697 1698 if (!scrollParent || scrollParent->stackingNode()->isStackingContainer()) 1699 return 0; 1700 1701 // If we hit a stacking context on our way up to the ancestor scrolling layer, it will already 1702 // be composited due to an overflow scrolling parent, so we don't need to. 1703 for (RenderLayer* ancestor = parent(); ancestor && ancestor != scrollParent; ancestor = ancestor->parent()) { 1704 if (ancestor->stackingNode()->isStackingContainer()) 1705 return 0; 1706 } 1707 1708 return scrollParent; 1709 } 1710 1711 RenderLayer* RenderLayer::clipParent() const 1712 { 1713 const bool needsAncestorClip = compositor()->clippedByAncestor(this); 1714 1715 RenderLayer* clipParent = 0; 1716 if ((compositingReasons() & CompositingReasonOutOfFlowClipping) && !needsAncestorClip) { 1717 if (RenderObject* containingBlock = renderer()->containingBlock()) 1718 clipParent = containingBlock->enclosingLayer()->enclosingCompositingLayer(true); 1719 } 1720 1721 return clipParent; 1722 } 1723 1724 void RenderLayer::didUpdateNeedsCompositedScrolling() 1725 { 1726 m_stackingNode->updateIsNormalFlowOnly(); 1727 updateSelfPaintingLayer(); 1728 1729 if (m_stackingNode->isStackingContainer()) 1730 m_stackingNode->dirtyZOrderLists(); 1731 else 1732 m_stackingNode->clearZOrderLists(); 1733 1734 m_stackingNode->dirtyStackingContainerZOrderLists(); 1735 1736 compositor()->setNeedsToRecomputeCompositingRequirements(); 1737 compositor()->setCompositingLayersNeedRebuild(); 1738 } 1739 1740 void RenderLayer::updateReflectionInfo(const RenderStyle* oldStyle) 1741 { 1742 if (renderer()->hasReflection()) { 1743 if (!m_reflectionInfo) 1744 m_reflectionInfo = adoptPtr(new RenderLayerReflectionInfo(toRenderBox(renderer()))); 1745 m_reflectionInfo->updateAfterStyleChange(oldStyle); 1746 } else if (m_reflectionInfo) { 1747 m_reflectionInfo = nullptr; 1748 } 1749 } 1750 1751 void RenderLayer::updateStackingNode() 1752 { 1753 if (requiresStackingNode()) 1754 m_stackingNode = adoptPtr(new RenderLayerStackingNode(this)); 1755 else 1756 m_stackingNode = nullptr; 1757 } 1758 1759 void RenderLayer::updateScrollableArea() 1760 { 1761 if (requiresScrollableArea()) 1762 m_scrollableArea = adoptPtr(new RenderLayerScrollableArea(renderBox())); 1763 else 1764 m_scrollableArea = nullptr; 1765 } 1766 1767 PassOwnPtr<Vector<FloatRect> > RenderLayer::collectTrackedRepaintRects() const 1768 { 1769 if (hasCompositedLayerMapping()) 1770 return compositedLayerMapping()->collectTrackedRepaintRects(); 1771 return nullptr; 1772 } 1773 1774 bool RenderLayer::hasOverflowControls() const 1775 { 1776 return m_scrollableArea && (m_scrollableArea->hasScrollbar() || m_scrollableArea->hasScrollCorner() || renderer()->style()->resize() != RESIZE_NONE); 1777 } 1778 1779 void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, RenderRegion* region, PaintLayerFlags paintFlags) 1780 { 1781 OverlapTestRequestMap overlapTestRequests; 1782 1783 LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot, region, &overlapTestRequests); 1784 paintLayer(context, paintingInfo, paintFlags); 1785 1786 OverlapTestRequestMap::iterator end = overlapTestRequests.end(); 1787 for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) 1788 it->key->setIsOverlapped(false); 1789 } 1790 1791 void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot) 1792 { 1793 if (!m_containsDirtyOverlayScrollbars) 1794 return; 1795 1796 LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot); 1797 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); 1798 1799 m_containsDirtyOverlayScrollbars = false; 1800 } 1801 1802 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLayer) 1803 { 1804 if (startLayer == endLayer) 1805 return true; 1806 1807 RenderView* view = startLayer->renderer()->view(); 1808 for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock(); currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlock()) { 1809 if (currentBlock->layer() == endLayer) 1810 return true; 1811 } 1812 1813 return false; 1814 } 1815 1816 void RenderLayer::clipToRect(RenderLayer* rootLayer, GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect, 1817 BorderRadiusClippingRule rule) 1818 { 1819 if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius()) 1820 return; 1821 context->save(); 1822 context->clip(pixelSnappedIntRect(clipRect.rect())); 1823 1824 if (!clipRect.hasRadius()) 1825 return; 1826 1827 // If the clip rect has been tainted by a border radius, then we have to walk up our layer chain applying the clips from 1828 // any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our 1829 // containing block chain so we check that also. 1830 for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) { 1831 if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(this, layer)) { 1832 LayoutPoint delta; 1833 layer->convertToLayerCoords(rootLayer, delta); 1834 context->clipRoundedRect(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size()))); 1835 } 1836 1837 if (layer == rootLayer) 1838 break; 1839 } 1840 } 1841 1842 void RenderLayer::restoreClip(GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect) 1843 { 1844 if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius()) 1845 return; 1846 context->restore(); 1847 } 1848 1849 static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, const RenderLayer* rootLayer, const RenderLayer* layer) 1850 { 1851 Vector<RenderWidget*> overlappedRequestClients; 1852 OverlapTestRequestMap::iterator end = overlapTestRequests.end(); 1853 LayoutRect boundingBox = layer->boundingBox(rootLayer); 1854 for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) { 1855 if (!boundingBox.intersects(it->value)) 1856 continue; 1857 1858 it->key->setIsOverlapped(true); 1859 overlappedRequestClients.append(it->key); 1860 } 1861 for (size_t i = 0; i < overlappedRequestClients.size(); ++i) 1862 overlapTestRequests.remove(overlappedRequestClients[i]); 1863 } 1864 1865 static bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflection) 1866 { 1867 return paintingReflection && !layer->has3DTransform(); 1868 } 1869 1870 static inline bool shouldSuppressPaintingLayer(RenderLayer* layer) 1871 { 1872 // Avoid painting descendants of the root layer when stylesheets haven't loaded. This eliminates FOUC. 1873 // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document 1874 // will do a full repaint(). 1875 if (layer->renderer()->document().didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer()->isRoot()) 1876 return true; 1877 1878 return false; 1879 } 1880 1881 static bool paintForFixedRootBackground(const RenderLayer* layer, PaintLayerFlags paintFlags) 1882 { 1883 return layer->renderer()->isRoot() && (paintFlags & PaintLayerPaintingRootBackgroundOnly); 1884 } 1885 1886 void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 1887 { 1888 if (compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking) { 1889 // The updatingControlTints() painting pass goes through compositing layers, 1890 // but we need to ensure that we don't cache clip rects computed with the wrong root in this case. 1891 if (context->updatingControlTints() || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers)) { 1892 paintFlags |= PaintLayerTemporaryClipRects; 1893 } else if (!compositedLayerMapping()->paintsIntoCompositedAncestor() 1894 && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection) 1895 && !paintForFixedRootBackground(this, paintFlags)) { 1896 // If this RenderLayer should paint into its own backing, that will be done via CompositedLayerMapping::paintIntoLayer(). 1897 return; 1898 } 1899 } else if (viewportConstrainedNotCompositedReason() == NotCompositedForBoundsOutOfView) { 1900 // Don't paint out-of-view viewport constrained layers (when doing prepainting) because they will never be visible 1901 // unless their position or viewport size is changed. 1902 return; 1903 } 1904 1905 // Non self-painting leaf layers don't need to be painted as their renderer() should properly paint itself. 1906 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) 1907 return; 1908 1909 if (shouldSuppressPaintingLayer(this)) 1910 return; 1911 1912 // If this layer is totally invisible then there is nothing to paint. 1913 if (!renderer()->opacity()) 1914 return; 1915 1916 if (paintsWithTransparency(paintingInfo.paintBehavior)) 1917 paintFlags |= PaintLayerHaveTransparency; 1918 1919 // PaintLayerAppliedTransform is used in RenderReplica, to avoid applying the transform twice. 1920 if (paintsWithTransform(paintingInfo.paintBehavior) && !(paintFlags & PaintLayerAppliedTransform)) { 1921 TransformationMatrix layerTransform = renderableTransform(paintingInfo.paintBehavior); 1922 // If the transform can't be inverted, then don't paint anything. 1923 if (!layerTransform.isInvertible()) 1924 return; 1925 1926 // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency 1927 // layer from the parent now, assuming there is a parent 1928 if (paintFlags & PaintLayerHaveTransparency) { 1929 if (parent()) 1930 parent()->beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior); 1931 else 1932 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior); 1933 } 1934 1935 if (enclosingPaginationLayer()) { 1936 paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags); 1937 return; 1938 } 1939 1940 // Make sure the parent's clip rects have been calculated. 1941 ClipRect clipRect = paintingInfo.paintDirtyRect; 1942 if (parent()) { 1943 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, paintingInfo.region, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, 1944 IgnoreOverlayScrollbarSize, (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip); 1945 clipRect = backgroundClipRect(clipRectsContext); 1946 clipRect.intersect(paintingInfo.paintDirtyRect); 1947 1948 // Push the parent coordinate space's clip. 1949 parent()->clipToRect(paintingInfo.rootLayer, context, paintingInfo.paintDirtyRect, clipRect); 1950 } 1951 1952 paintLayerByApplyingTransform(context, paintingInfo, paintFlags); 1953 1954 // Restore the clip. 1955 if (parent()) 1956 parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect); 1957 1958 return; 1959 } 1960 1961 paintLayerContentsAndReflection(context, paintingInfo, paintFlags); 1962 } 1963 1964 void RenderLayer::paintLayerContentsAndReflection(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 1965 { 1966 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 1967 1968 PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform); 1969 1970 // Paint the reflection first if we have one. 1971 if (m_reflectionInfo) 1972 m_reflectionInfo->paint(context, paintingInfo, localPaintFlags | PaintLayerPaintingReflection); 1973 1974 localPaintFlags |= PaintLayerPaintingCompositingAllPhases; 1975 paintLayerContents(context, paintingInfo, localPaintFlags); 1976 } 1977 1978 void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 1979 { 1980 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 1981 ASSERT(!(paintFlags & PaintLayerAppliedTransform)); 1982 1983 bool haveTransparency = paintFlags & PaintLayerHaveTransparency; 1984 bool isSelfPaintingLayer = this->isSelfPaintingLayer(); 1985 bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars; 1986 bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositingScrollingPhase; 1987 bool isPaintingCompositedForeground = paintFlags & PaintLayerPaintingCompositingForegroundPhase; 1988 bool isPaintingCompositedBackground = paintFlags & PaintLayerPaintingCompositingBackgroundPhase; 1989 bool isPaintingOverflowContents = paintFlags & PaintLayerPaintingOverflowContents; 1990 // Outline always needs to be painted even if we have no visible content. Also, 1991 // the outline is painted in the background phase during composited scrolling. 1992 // If it were painted in the foreground phase, it would move with the scrolled 1993 // content. When not composited scrolling, the outline is painted in the 1994 // foreground phase. Since scrolled contents are moved by repainting in this 1995 // case, the outline won't get 'dragged along'. 1996 bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars 1997 && ((isPaintingScrollingContent && isPaintingCompositedBackground) 1998 || (!isPaintingScrollingContent && isPaintingCompositedForeground)); 1999 bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars; 2000 2001 float deviceScaleFactor = WebCore::deviceScaleFactor(renderer()->frame()); 2002 context->setUseHighResMarkers(deviceScaleFactor > 1.5f); 2003 2004 GraphicsContext* transparencyLayerContext = context; 2005 2006 if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isRoot()) 2007 return; 2008 2009 // Ensure our lists are up-to-date. 2010 m_stackingNode->updateLayerListsIfNeeded(); 2011 2012 LayoutPoint offsetFromRoot; 2013 convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); 2014 2015 IntRect rootRelativeBounds; 2016 bool rootRelativeBoundsComputed = false; 2017 2018 // Apply clip-path to context. 2019 bool hasClipPath = false; 2020 RenderStyle* style = renderer()->style(); 2021 RenderSVGResourceClipper* resourceClipper = 0; 2022 ClipperContext clipperContext; 2023 if (renderer()->hasClipPath() && !context->paintingDisabled() && style) { 2024 ASSERT(style->clipPath()); 2025 if (style->clipPath()->type() == ClipPathOperation::SHAPE) { 2026 hasClipPath = true; 2027 context->save(); 2028 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->clipPath()); 2029 2030 if (!rootRelativeBoundsComputed) { 2031 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0); 2032 rootRelativeBoundsComputed = true; 2033 } 2034 2035 context->clipPath(clipPath->path(rootRelativeBounds), clipPath->windRule()); 2036 } else if (style->clipPath()->type() == ClipPathOperation::REFERENCE) { 2037 ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClipPathOperation(style->clipPath()); 2038 Document& document = renderer()->document(); 2039 // FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405) 2040 Element* element = document.getElementById(referenceClipPathOperation->fragment()); 2041 if (element && element->hasTagName(SVGNames::clipPathTag) && element->renderer()) { 2042 if (!rootRelativeBoundsComputed) { 2043 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0); 2044 rootRelativeBoundsComputed = true; 2045 } 2046 2047 resourceClipper = toRenderSVGResourceClipper(toRenderSVGResourceContainer(element->renderer())); 2048 if (!resourceClipper->applyClippingToContext(renderer(), rootRelativeBounds, 2049 paintingInfo.paintDirtyRect, context, clipperContext)) { 2050 // No need to post-apply the clipper if this failed. 2051 resourceClipper = 0; 2052 } 2053 } 2054 } 2055 } 2056 2057 // Blending operations must be performed only with the nearest ancestor stacking context. 2058 // Note that there is no need to create a transparency layer if we're painting the root. 2059 bool createTransparencyLayerForBlendMode = !renderer()->isRoot() && m_stackingNode->isStackingContext() && m_childLayerHasBlendMode; 2060 2061 if (createTransparencyLayerForBlendMode) 2062 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior); 2063 2064 LayerPaintingInfo localPaintingInfo(paintingInfo); 2065 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters()); 2066 if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) { 2067 RenderLayerFilterInfo* filterInfo = this->filterInfo(); 2068 ASSERT(filterInfo); 2069 LayoutRect filterRepaintRect = filterInfo->dirtySourceRect(); 2070 filterRepaintRect.move(offsetFromRoot.x(), offsetFromRoot.y()); 2071 2072 if (!rootRelativeBoundsComputed) { 2073 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0); 2074 rootRelativeBoundsComputed = true; 2075 } 2076 2077 if (filterPainter.prepareFilterEffect(this, rootRelativeBounds, paintingInfo.paintDirtyRect, filterRepaintRect)) { 2078 // Now we know for sure, that the source image will be updated, so we can revert our tracking repaint rect back to zero. 2079 filterInfo->resetDirtySourceRect(); 2080 2081 // Rewire the old context to a memory buffer, so that we can capture the contents of the layer. 2082 // NOTE: We saved the old context in the "transparencyLayerContext" local variable, to be able to start a transparency layer 2083 // on the original context and avoid duplicating "beginFilterEffect" after each transparency layer call. Also, note that 2084 // beginTransparencyLayers will only create a single lazy transparency layer, even though it is called twice in this method. 2085 context = filterPainter.beginFilterEffect(context); 2086 2087 // Check that we didn't fail to allocate the graphics context for the offscreen buffer. 2088 if (filterPainter.hasStartedFilterEffect()) { 2089 localPaintingInfo.paintDirtyRect = filterPainter.repaintRect(); 2090 // If the filter needs the full source image, we need to avoid using the clip rectangles. 2091 // Otherwise, if for example this layer has overflow:hidden, a drop shadow will not compute correctly. 2092 // Note that we will still apply the clipping on the final rendering of the filter. 2093 localPaintingInfo.clipToDirtyRect = !filterRenderer()->hasFilterThatMovesPixels(); 2094 } 2095 } 2096 } 2097 2098 if (filterPainter.hasStartedFilterEffect() && haveTransparency) { 2099 // 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. 2100 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior); 2101 } 2102 2103 // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which 2104 // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set). 2105 // Else, our renderer tree may or may not contain the painting root, so we pass that root along 2106 // so it will be tested against as we descend through the renderers. 2107 RenderObject* paintingRootForRenderer = 0; 2108 if (localPaintingInfo.paintingRoot && !renderer()->isDescendantOf(localPaintingInfo.paintingRoot)) 2109 paintingRootForRenderer = localPaintingInfo.paintingRoot; 2110 2111 if (localPaintingInfo.overlapTestRequests && isSelfPaintingLayer) 2112 performOverlapTests(*localPaintingInfo.overlapTestRequests, localPaintingInfo.rootLayer, this); 2113 2114 bool forceBlackText = localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText; 2115 bool selectionOnly = localPaintingInfo.paintBehavior & PaintBehaviorSelectionOnly; 2116 2117 bool shouldPaintBackground = isPaintingCompositedBackground && shouldPaintContent && !selectionOnly; 2118 bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground); 2119 bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPaintContent; 2120 bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForeground; 2121 bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars; 2122 bool shouldPaintMask = (paintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && renderer()->hasMask() && !selectionOnly; 2123 bool shouldPaintClippingMask = (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && shouldPaintContent && !selectionOnly; 2124 2125 PaintBehavior paintBehavior = PaintBehaviorNormal; 2126 if (paintFlags & PaintLayerPaintingSkipRootBackground) 2127 paintBehavior |= PaintBehaviorSkipRootBackground; 2128 else if (paintFlags & PaintLayerPaintingRootBackgroundOnly) 2129 paintBehavior |= PaintBehaviorRootBackgroundOnly; 2130 2131 LayerFragments layerFragments; 2132 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) { 2133 // 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 2134 // fragment should paint. 2135 collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.region, localPaintingInfo.paintDirtyRect, 2136 (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize, 2137 (isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetFromRoot); 2138 updatePaintingInfoForFragments(layerFragments, localPaintingInfo, paintFlags, shouldPaintContent, &offsetFromRoot); 2139 } 2140 2141 if (shouldPaintBackground) 2142 paintBackgroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency, 2143 localPaintingInfo, paintBehavior, paintingRootForRenderer); 2144 2145 if (shouldPaintNegZOrderList) 2146 paintChildren(NegativeZOrderChildren, context, localPaintingInfo, paintFlags); 2147 2148 if (shouldPaintOwnContents) 2149 paintForegroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency, 2150 localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, forceBlackText); 2151 2152 if (shouldPaintOutline) 2153 paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer); 2154 2155 if (shouldPaintNormalFlowAndPosZOrderLists) 2156 paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, localPaintingInfo, paintFlags); 2157 2158 if (shouldPaintOverlayScrollbars) 2159 paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo); 2160 2161 if (filterPainter.hasStartedFilterEffect()) { 2162 // Apply the correct clipping (ie. overflow: hidden). 2163 // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved. 2164 ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect; 2165 clipToRect(localPaintingInfo.rootLayer, transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect); 2166 context = filterPainter.applyFilterEffect(); 2167 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect); 2168 } 2169 2170 // Make sure that we now use the original transparency context. 2171 ASSERT(transparencyLayerContext == context); 2172 2173 if (shouldPaintMask) 2174 paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer); 2175 2176 if (shouldPaintClippingMask) { 2177 // Paint the border radius mask for the fragments. 2178 paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer); 2179 } 2180 2181 // End our transparency layer 2182 if ((haveTransparency || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency && !(m_reflectionInfo && m_reflectionInfo->isPaintingInsideReflection())) { 2183 context->endLayer(); 2184 context->restore(); 2185 m_usedTransparency = false; 2186 } 2187 2188 if (resourceClipper) 2189 resourceClipper->postApplyStatefulResource(renderer(), context, clipperContext); 2190 2191 if (hasClipPath) 2192 context->restore(); 2193 } 2194 2195 void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& translationOffset) 2196 { 2197 // This involves subtracting out the position of the layer in our current coordinate space, but preserving 2198 // the accumulated error for sub-pixel layout. 2199 LayoutPoint delta; 2200 convertToLayerCoords(paintingInfo.rootLayer, delta); 2201 delta.moveBy(translationOffset); 2202 TransformationMatrix transform(renderableTransform(paintingInfo.paintBehavior)); 2203 IntPoint roundedDelta = roundedIntPoint(delta); 2204 transform.translateRight(roundedDelta.x(), roundedDelta.y()); 2205 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta); 2206 2207 // Apply the transform. 2208 GraphicsContextStateSaver stateSaver(*context); 2209 context->concatCTM(transform.toAffineTransform()); 2210 2211 // Now do a paint with the root layer shifted to be us. 2212 LayerPaintingInfo transformedPaintingInfo(this, enclosingIntRect(transform.inverse().mapRect(paintingInfo.paintDirtyRect)), paintingInfo.paintBehavior, 2213 adjustedSubPixelAccumulation, paintingInfo.paintingRoot, paintingInfo.region, paintingInfo.overlapTestRequests); 2214 paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags); 2215 } 2216 2217 void RenderLayer::paintChildren(unsigned childrenToVisit, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 2218 { 2219 if (!hasSelfPaintingLayerDescendant()) 2220 return; 2221 2222 #if !ASSERT_DISABLED 2223 LayerListMutationDetector mutationChecker(m_stackingNode.get()); 2224 #endif 2225 2226 RenderLayerStackingNodeIterator iterator(*m_stackingNode, childrenToVisit); 2227 while (RenderLayerStackingNode* child = iterator.next()) { 2228 RenderLayer* childLayer = child->layer(); 2229 2230 // Squashed RenderLayers should not paint into their ancestor. 2231 if (childLayer->compositingState() == PaintsIntoGroupedBacking) 2232 continue; 2233 2234 if (!childLayer->isPaginated()) 2235 childLayer->paintLayer(context, paintingInfo, paintFlags); 2236 else 2237 paintPaginatedChildLayer(childLayer, context, paintingInfo, paintFlags); 2238 } 2239 } 2240 2241 void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, RenderRegion* region, const LayoutRect& dirtyRect, 2242 ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot, 2243 const LayoutRect* layerBoundingBox) 2244 { 2245 if (!enclosingPaginationLayer() || hasTransform()) { 2246 // For unpaginated layers, there is only one fragment. 2247 LayerFragment fragment; 2248 ClipRectsContext clipRectsContext(rootLayer, region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip); 2249 calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot); 2250 fragments.append(fragment); 2251 return; 2252 } 2253 2254 // Compute our offset within the enclosing pagination layer. 2255 LayoutPoint offsetWithinPaginatedLayer; 2256 convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginatedLayer); 2257 2258 // Calculate clip rects relative to the enclosingPaginationLayer. The purpose of this call is to determine our bounds clipped to intermediate 2259 // 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. 2260 ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip); 2261 LayoutRect layerBoundsInFlowThread; 2262 ClipRect backgroundRectInFlowThread; 2263 ClipRect foregroundRectInFlowThread; 2264 ClipRect outlineRectInFlowThread; 2265 calculateRects(paginationClipRectsContext, PaintInfo::infiniteRect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, 2266 outlineRectInFlowThread, &offsetWithinPaginatedLayer); 2267 2268 // Take our bounding box within the flow thread and clip it. 2269 LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : boundingBox(enclosingPaginationLayer(), 0, &offsetWithinPaginatedLayer); 2270 layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect()); 2271 2272 // Shift the dirty rect into flow thread coordinates. 2273 LayoutPoint offsetOfPaginationLayerFromRoot; 2274 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot); 2275 LayoutRect dirtyRectInFlowThread(dirtyRect); 2276 dirtyRectInFlowThread.moveBy(-offsetOfPaginationLayerFromRoot); 2277 2278 // Tell the flow thread to collect the fragments. We pass enough information to create a minimal number of fragments based off the pages/columns 2279 // that intersect the actual dirtyRect as well as the pages/columns that intersect our layer's bounding box. 2280 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer()); 2281 enclosingFlowThread->collectLayerFragments(fragments, layerBoundingBoxInFlowThread, dirtyRectInFlowThread); 2282 2283 if (fragments.isEmpty()) 2284 return; 2285 2286 // Get the parent clip rects of the pagination layer, since we need to intersect with that when painting column contents. 2287 ClipRect ancestorClipRect = dirtyRect; 2288 if (enclosingPaginationLayer()->parent()) { 2289 ClipRectsContext clipRectsContext(rootLayer, region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip); 2290 ancestorClipRect = enclosingPaginationLayer()->backgroundClipRect(clipRectsContext); 2291 ancestorClipRect.intersect(dirtyRect); 2292 } 2293 2294 for (size_t i = 0; i < fragments.size(); ++i) { 2295 LayerFragment& fragment = fragments.at(i); 2296 2297 // Set our four rects with all clipping applied that was internal to the flow thread. 2298 fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, outlineRectInFlowThread); 2299 2300 // Shift to the root-relative physical position used when painting the flow thread in this fragment. 2301 fragment.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot); 2302 2303 // Intersect the fragment with our ancestor's background clip so that e.g., columns in an overflow:hidden block are 2304 // properly clipped by the overflow. 2305 fragment.intersect(ancestorClipRect.rect()); 2306 2307 // Now intersect with our pagination clip. This will typically mean we're just intersecting the dirty rect with the column 2308 // clip, so the column clip ends up being all we apply. 2309 fragment.intersect(fragment.paginationClip); 2310 } 2311 } 2312 2313 void RenderLayer::updatePaintingInfoForFragments(LayerFragments& fragments, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags localPaintFlags, 2314 bool shouldPaintContent, const LayoutPoint* offsetFromRoot) 2315 { 2316 ASSERT(offsetFromRoot); 2317 for (size_t i = 0; i < fragments.size(); ++i) { 2318 LayerFragment& fragment = fragments.at(i); 2319 fragment.shouldPaintContent = shouldPaintContent; 2320 if (this != localPaintingInfo.rootLayer || !(localPaintFlags & PaintLayerPaintingOverflowContents)) { 2321 LayoutPoint newOffsetFromRoot = *offsetFromRoot + fragment.paginationOffset; 2322 fragment.shouldPaintContent &= intersectsDamageRect(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLayer, &newOffsetFromRoot); 2323 } 2324 } 2325 } 2326 2327 void RenderLayer::paintTransformedLayerIntoFragments(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 2328 { 2329 LayerFragments enclosingPaginationFragments; 2330 LayoutPoint offsetOfPaginationLayerFromRoot; 2331 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.paintBehavior); 2332 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.region, paintingInfo.paintDirtyRect, 2333 (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize, 2334 (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetOfPaginationLayerFromRoot, &transformedExtent); 2335 2336 for (size_t i = 0; i < enclosingPaginationFragments.size(); ++i) { 2337 const LayerFragment& fragment = enclosingPaginationFragments.at(i); 2338 2339 // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and 2340 // the enclosing pagination layer. 2341 LayoutRect clipRect = fragment.backgroundRect.rect(); 2342 2343 // Now compute the clips within a given fragment 2344 if (parent() != enclosingPaginationLayer()) { 2345 enclosingPaginationLayer()->convertToLayerCoords(paintingInfo.rootLayer, offsetOfPaginationLayerFromRoot); 2346 2347 ClipRectsContext clipRectsContext(enclosingPaginationLayer(), paintingInfo.region, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, 2348 IgnoreOverlayScrollbarSize, (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip); 2349 LayoutRect parentClipRect = backgroundClipRect(clipRectsContext).rect(); 2350 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot); 2351 clipRect.intersect(parentClipRect); 2352 } 2353 2354 parent()->clipToRect(paintingInfo.rootLayer, context, paintingInfo.paintDirtyRect, clipRect); 2355 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset); 2356 parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect); 2357 } 2358 } 2359 2360 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext, 2361 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 2362 RenderObject* paintingRootForRenderer) 2363 { 2364 for (size_t i = 0; i < layerFragments.size(); ++i) { 2365 const LayerFragment& fragment = layerFragments.at(i); 2366 if (!fragment.shouldPaintContent) 2367 continue; 2368 2369 // Begin transparency layers lazily now that we know we have to paint something. 2370 if (haveTransparency || paintsWithBlendMode()) 2371 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior); 2372 2373 if (localPaintingInfo.clipToDirtyRect) { 2374 // Paint our background first, before painting any child layers. 2375 // Establish the clip used to paint our background. 2376 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self. 2377 } 2378 2379 // Paint the background. 2380 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info. 2381 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer()); 2382 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation)); 2383 2384 if (localPaintingInfo.clipToDirtyRect) 2385 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect); 2386 } 2387 } 2388 2389 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext, 2390 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 2391 RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackText) 2392 { 2393 // Begin transparency if we have something to paint. 2394 if (haveTransparency || paintsWithBlendMode()) { 2395 for (size_t i = 0; i < layerFragments.size(); ++i) { 2396 const LayerFragment& fragment = layerFragments.at(i); 2397 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty()) { 2398 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior); 2399 break; 2400 } 2401 } 2402 } 2403 2404 PaintBehavior localPaintBehavior = forceBlackText ? (PaintBehavior)PaintBehaviorForceBlackText : paintBehavior; 2405 2406 // Optimize clipping for the single fragment case. 2407 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty(); 2408 if (shouldClip) 2409 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect); 2410 2411 // We have to loop through every fragment multiple times, since we have to repaint in each specific phase in order for 2412 // interleaving of the fragments to work properly. 2413 paintForegroundForFragmentsWithPhase(selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds, layerFragments, 2414 context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer); 2415 2416 if (!selectionOnly) { 2417 paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer); 2418 paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer); 2419 paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer); 2420 } 2421 2422 if (shouldClip) 2423 restoreClip(context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect); 2424 } 2425 2426 void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const LayerFragments& layerFragments, GraphicsContext* context, 2427 const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer) 2428 { 2429 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() > 1; 2430 2431 for (size_t i = 0; i < layerFragments.size(); ++i) { 2432 const LayerFragment& fragment = layerFragments.at(i); 2433 if (!fragment.shouldPaintContent || fragment.foregroundRect.isEmpty()) 2434 continue; 2435 2436 if (shouldClip) 2437 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect); 2438 2439 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer()); 2440 if (phase == PaintPhaseForeground) 2441 paintInfo.overlapTestRequests = localPaintingInfo.overlapTestRequests; 2442 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation)); 2443 2444 if (shouldClip) 2445 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect); 2446 } 2447 } 2448 2449 void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo, 2450 PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer) 2451 { 2452 for (size_t i = 0; i < layerFragments.size(); ++i) { 2453 const LayerFragment& fragment = layerFragments.at(i); 2454 if (fragment.outlineRect.isEmpty()) 2455 continue; 2456 2457 // Paint our own outline 2458 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer()); 2459 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.outlineRect, DoNotIncludeSelfForBorderRadius); 2460 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation)); 2461 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.outlineRect); 2462 } 2463 } 2464 2465 void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo, 2466 RenderObject* paintingRootForRenderer) 2467 { 2468 for (size_t i = 0; i < layerFragments.size(); ++i) { 2469 const LayerFragment& fragment = layerFragments.at(i); 2470 if (!fragment.shouldPaintContent) 2471 continue; 2472 2473 if (localPaintingInfo.clipToDirtyRect) 2474 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self. 2475 2476 // Paint the mask. 2477 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info. 2478 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer()); 2479 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation)); 2480 2481 if (localPaintingInfo.clipToDirtyRect) 2482 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect); 2483 } 2484 } 2485 2486 void RenderLayer::paintChildClippingMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo, 2487 RenderObject* paintingRootForRenderer) 2488 { 2489 for (size_t i = 0; i < layerFragments.size(); ++i) { 2490 const LayerFragment& fragment = layerFragments.at(i); 2491 if (!fragment.shouldPaintContent) 2492 continue; 2493 2494 if (localPaintingInfo.clipToDirtyRect) 2495 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self. 2496 2497 // Paint the the clipped mask. 2498 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseClippingMask, PaintBehaviorNormal, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer()); 2499 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation)); 2500 2501 if (localPaintingInfo.clipToDirtyRect) 2502 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect); 2503 } 2504 } 2505 2506 void RenderLayer::paintOverflowControlsForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo) 2507 { 2508 for (size_t i = 0; i < layerFragments.size(); ++i) { 2509 const LayerFragment& fragment = layerFragments.at(i); 2510 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect); 2511 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea()) 2512 scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation)), pixelSnappedIntRect(fragment.backgroundRect.rect()), true); 2513 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect); 2514 } 2515 } 2516 2517 void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 2518 { 2519 // We need to do multiple passes, breaking up our child layer into strips. 2520 Vector<RenderLayer*> columnLayers; 2521 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContainerNode(); 2522 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) { 2523 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox())) 2524 columnLayers.append(curr); 2525 if (curr->stackingNode() == ancestorNode) 2526 break; 2527 } 2528 2529 // It is possible for paintLayer() to be called after the child layer ceases to be paginated but before 2530 // updateLayerPositions() is called and resets the isPaginated() flag, see <rdar://problem/10098679>. 2531 // If this is the case, just bail out, since the upcoming call to updateLayerPositions() will repaint the layer. 2532 if (!columnLayers.size()) 2533 return; 2534 2535 paintChildLayerIntoColumns(childLayer, context, paintingInfo, paintFlags, columnLayers, columnLayers.size() - 1); 2536 } 2537 2538 void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, 2539 PaintLayerFlags paintFlags, const Vector<RenderLayer*>& columnLayers, size_t colIndex) 2540 { 2541 RenderBlock* columnBlock = toRenderBlock(columnLayers[colIndex]->renderer()); 2542 2543 ASSERT(columnBlock && columnBlock->hasColumns()); 2544 if (!columnBlock || !columnBlock->hasColumns()) 2545 return; 2546 2547 LayoutPoint layerOffset; 2548 // FIXME: It looks suspicious to call convertToLayerCoords here 2549 // as canUseConvertToLayerCoords is true for this layer. 2550 columnBlock->layer()->convertToLayerCoords(paintingInfo.rootLayer, layerOffset); 2551 2552 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode(); 2553 2554 ColumnInfo* colInfo = columnBlock->columnInfo(); 2555 unsigned colCount = columnBlock->columnCount(colInfo); 2556 LayoutUnit currLogicalTopOffset = 0; 2557 for (unsigned i = 0; i < colCount; i++) { 2558 // For each rect, we clip to the rect, and then we adjust our coords. 2559 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i); 2560 columnBlock->flipForWritingMode(colRect); 2561 LayoutUnit logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent(); 2562 LayoutSize offset; 2563 if (isHorizontal) { 2564 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) 2565 offset = LayoutSize(logicalLeftOffset, currLogicalTopOffset); 2566 else 2567 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop()); 2568 } else { 2569 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) 2570 offset = LayoutSize(currLogicalTopOffset, logicalLeftOffset); 2571 else 2572 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0); 2573 } 2574 2575 colRect.moveBy(layerOffset); 2576 2577 LayoutRect localDirtyRect(paintingInfo.paintDirtyRect); 2578 localDirtyRect.intersect(colRect); 2579 2580 if (!localDirtyRect.isEmpty()) { 2581 GraphicsContextStateSaver stateSaver(*context); 2582 2583 // Each strip pushes a clip, since column boxes are specified as being 2584 // like overflow:hidden. 2585 context->clip(pixelSnappedIntRect(colRect)); 2586 2587 if (!colIndex) { 2588 // Apply a translation transform to change where the layer paints. 2589 TransformationMatrix oldTransform; 2590 bool oldHasTransform = childLayer->transform(); 2591 if (oldHasTransform) 2592 oldTransform = *childLayer->transform(); 2593 TransformationMatrix newTransform(oldTransform); 2594 newTransform.translateRight(roundToInt(offset.width()), roundToInt(offset.height())); 2595 2596 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform)); 2597 2598 LayerPaintingInfo localPaintingInfo(paintingInfo); 2599 localPaintingInfo.paintDirtyRect = localDirtyRect; 2600 childLayer->paintLayer(context, localPaintingInfo, paintFlags); 2601 2602 if (oldHasTransform) 2603 childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform)); 2604 else 2605 childLayer->m_transform.clear(); 2606 } else { 2607 // Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space. 2608 // This involves subtracting out the position of the layer in our current coordinate space. 2609 LayoutPoint childOffset; 2610 columnLayers[colIndex - 1]->convertToLayerCoords(paintingInfo.rootLayer, childOffset); 2611 TransformationMatrix transform; 2612 transform.translateRight(roundToInt(childOffset.x() + offset.width()), roundToInt(childOffset.y() + offset.height())); 2613 2614 // Apply the transform. 2615 context->concatCTM(transform.toAffineTransform()); 2616 2617 // Now do a paint with the root layer shifted to be the next multicol block. 2618 LayerPaintingInfo columnPaintingInfo(paintingInfo); 2619 columnPaintingInfo.rootLayer = columnLayers[colIndex - 1]; 2620 columnPaintingInfo.paintDirtyRect = transform.inverse().mapRect(localDirtyRect); 2621 paintChildLayerIntoColumns(childLayer, context, columnPaintingInfo, paintFlags, columnLayers, colIndex - 1); 2622 } 2623 } 2624 2625 // Move to the next position. 2626 LayoutUnit blockDelta = isHorizontal ? colRect.height() : colRect.width(); 2627 if (columnBlock->style()->isFlippedBlocksWritingMode()) 2628 currLogicalTopOffset += blockDelta; 2629 else 2630 currLogicalTopOffset -= blockDelta; 2631 } 2632 } 2633 2634 static inline LayoutRect frameVisibleRect(RenderObject* renderer) 2635 { 2636 FrameView* frameView = renderer->document().view(); 2637 if (!frameView) 2638 return LayoutRect(); 2639 2640 return frameView->visibleContentRect(); 2641 } 2642 2643 bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result) 2644 { 2645 return hitTest(request, result.hitTestLocation(), result); 2646 } 2647 2648 bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation& hitTestLocation, HitTestResult& result) 2649 { 2650 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 2651 2652 // RenderView should make sure to update layout before entering hit testing 2653 ASSERT(!renderer()->frame()->view()->layoutPending()); 2654 ASSERT(!renderer()->document().renderer()->needsLayout()); 2655 2656 LayoutRect hitTestArea = isOutOfFlowRenderFlowThread() ? toRenderFlowThread(renderer())->borderBoxRect() : renderer()->view()->documentRect(); 2657 if (!request.ignoreClipping()) 2658 hitTestArea.intersect(frameVisibleRect(renderer())); 2659 2660 RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestArea, hitTestLocation, false); 2661 if (!insideLayer) { 2662 // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down, 2663 // return ourselves. We do this so mouse events continue getting delivered after a drag has 2664 // exited the WebView, and so hit testing over a scrollbar hits the content document. 2665 if (!request.isChildFrameHitTest() && (request.active() || request.release()) && isRootLayer()) { 2666 renderer()->updateHitTestResult(result, toRenderView(renderer())->flipForWritingMode(hitTestLocation.point())); 2667 insideLayer = this; 2668 } 2669 } 2670 2671 // Now determine if the result is inside an anchor - if the urlElement isn't already set. 2672 Node* node = result.innerNode(); 2673 if (node && !result.URLElement()) 2674 result.setURLElement(toElement(node->enclosingLinkEventParentOrSelf())); 2675 2676 // Now return whether we were inside this layer (this will always be true for the root 2677 // layer). 2678 return insideLayer; 2679 } 2680 2681 Node* RenderLayer::enclosingElement() const 2682 { 2683 for (RenderObject* r = renderer(); r; r = r->parent()) { 2684 if (Node* e = r->node()) 2685 return e; 2686 } 2687 ASSERT_NOT_REACHED(); 2688 return 0; 2689 } 2690 2691 bool RenderLayer::isInTopLayer() const 2692 { 2693 Node* node = renderer()->node(); 2694 return node && node->isElementNode() && toElement(node)->isInTopLayer(); 2695 } 2696 2697 bool RenderLayer::isInTopLayerSubtree() const 2698 { 2699 for (const RenderLayer* layer = this; layer; layer = layer->parent()) { 2700 if (layer->isInTopLayer()) 2701 return true; 2702 } 2703 return false; 2704 } 2705 2706 // Compute the z-offset of the point in the transformState. 2707 // This is effectively projecting a ray normal to the plane of ancestor, finding where that 2708 // ray intersects target, and computing the z delta between those two points. 2709 static double computeZOffset(const HitTestingTransformState& transformState) 2710 { 2711 // We got an affine transform, so no z-offset 2712 if (transformState.m_accumulatedTransform.isAffine()) 2713 return 0; 2714 2715 // Flatten the point into the target plane 2716 FloatPoint targetPoint = transformState.mappedPoint(); 2717 2718 // Now map the point back through the transform, which computes Z. 2719 FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint)); 2720 return backmappedPoint.z(); 2721 } 2722 2723 PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer, 2724 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, 2725 const HitTestingTransformState* containerTransformState, 2726 const LayoutPoint& translationOffset) const 2727 { 2728 RefPtr<HitTestingTransformState> transformState; 2729 LayoutPoint offset; 2730 if (containerTransformState) { 2731 // If we're already computing transform state, then it's relative to the container (which we know is non-null). 2732 transformState = HitTestingTransformState::create(*containerTransformState); 2733 convertToLayerCoords(containerLayer, offset); 2734 } else { 2735 // If this is the first time we need to make transform state, then base it off of hitTestLocation, 2736 // which is relative to rootLayer. 2737 transformState = HitTestingTransformState::create(hitTestLocation.transformedPoint(), hitTestLocation.transformedRect(), FloatQuad(hitTestRect)); 2738 convertToLayerCoords(rootLayer, offset); 2739 } 2740 offset.moveBy(translationOffset); 2741 2742 RenderObject* containerRenderer = containerLayer ? containerLayer->renderer() : 0; 2743 if (renderer()->shouldUseTransformFromContainer(containerRenderer)) { 2744 TransformationMatrix containerTransform; 2745 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(offset), containerTransform); 2746 transformState->applyTransform(containerTransform, HitTestingTransformState::AccumulateTransform); 2747 } else { 2748 transformState->translate(offset.x(), offset.y(), HitTestingTransformState::AccumulateTransform); 2749 } 2750 2751 return transformState; 2752 } 2753 2754 2755 static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, double* zOffset, const HitTestingTransformState* transformState) 2756 { 2757 if (!hitLayer) 2758 return false; 2759 2760 // The hit layer is depth-sorting with other layers, so just say that it was hit. 2761 if (canDepthSort) 2762 return true; 2763 2764 // We need to look at z-depth to decide if this layer was hit. 2765 if (zOffset) { 2766 ASSERT(transformState); 2767 // This is actually computing our z, but that's OK because the hitLayer is coplanar with us. 2768 double childZOffset = computeZOffset(*transformState); 2769 if (childZOffset > *zOffset) { 2770 *zOffset = childZOffset; 2771 return true; 2772 } 2773 return false; 2774 } 2775 2776 return true; 2777 } 2778 2779 // hitTestLocation and hitTestRect are relative to rootLayer. 2780 // A 'flattening' layer is one preserves3D() == false. 2781 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer. 2782 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the containing flattening layer. 2783 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer. 2784 // 2785 // If zOffset is non-null (which indicates that the caller wants z offset information), 2786 // *zOffset on return is the z offset of the hit point relative to the containing flattening layer. 2787 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result, 2788 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, bool appliedTransform, 2789 const HitTestingTransformState* transformState, double* zOffset) 2790 { 2791 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) 2792 return 0; 2793 2794 // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate. 2795 2796 // Apply a transform if we have one. 2797 if (transform() && !appliedTransform) { 2798 if (enclosingPaginationLayer()) 2799 return hitTestTransformedLayerInFragments(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset); 2800 2801 // Make sure the parent's clip rects have been calculated. 2802 if (parent()) { 2803 ClipRectsContext clipRectsContext(rootLayer, hitTestLocation.region(), RootRelativeClipRects, IncludeOverlayScrollbarSize); 2804 ClipRect clipRect = backgroundClipRect(clipRectsContext); 2805 // Go ahead and test the enclosing clip now. 2806 if (!clipRect.intersects(hitTestLocation)) 2807 return 0; 2808 } 2809 2810 return hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset); 2811 } 2812 2813 // Ensure our lists and 3d status are up-to-date. 2814 m_stackingNode->updateLayerListsIfNeeded(); 2815 update3DTransformedDescendantStatus(); 2816 2817 RefPtr<HitTestingTransformState> localTransformState; 2818 if (appliedTransform) { 2819 // We computed the correct state in the caller (above code), so just reference it. 2820 ASSERT(transformState); 2821 localTransformState = const_cast<HitTestingTransformState*>(transformState); 2822 } else if (transformState || m_has3DTransformedDescendant || preserves3D()) { 2823 // We need transform state for the first time, or to offset the container state, so create it here. 2824 localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState); 2825 } 2826 2827 // Check for hit test on backface if backface-visibility is 'hidden' 2828 if (localTransformState && renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) { 2829 TransformationMatrix invertedMatrix = localTransformState->m_accumulatedTransform.inverse(); 2830 // If the z-vector of the matrix is negative, the back is facing towards the viewer. 2831 if (invertedMatrix.m33() < 0) 2832 return 0; 2833 } 2834 2835 RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformState; 2836 if (localTransformState && !preserves3D()) { 2837 // Keep a copy of the pre-flattening state, for computing z-offsets for the container 2838 unflattenedTransformState = HitTestingTransformState::create(*localTransformState); 2839 // This layer is flattening, so flatten the state passed to descendants. 2840 localTransformState->flatten(); 2841 } 2842 2843 // The following are used for keeping track of the z-depth of the hit point of 3d-transformed 2844 // descendants. 2845 double localZOffset = -numeric_limits<double>::infinity(); 2846 double* zOffsetForDescendantsPtr = 0; 2847 double* zOffsetForContentsPtr = 0; 2848 2849 bool depthSortDescendants = false; 2850 if (preserves3D()) { 2851 depthSortDescendants = true; 2852 // Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down. 2853 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset; 2854 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset; 2855 } else if (m_has3DTransformedDescendant) { 2856 // Flattening layer with 3d children; use a local zOffset pointer to depth-test children and foreground. 2857 depthSortDescendants = true; 2858 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset; 2859 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset; 2860 } else if (zOffset) { 2861 zOffsetForDescendantsPtr = 0; 2862 // Container needs us to give back a z offset for the hit layer. 2863 zOffsetForContentsPtr = zOffset; 2864 } 2865 2866 // This variable tracks which layer the mouse ends up being inside. 2867 RenderLayer* candidateLayer = 0; 2868 2869 // Begin by walking our list of positive layers from highest z-index down to the lowest z-index. 2870 RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation, 2871 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); 2872 if (hitLayer) { 2873 if (!depthSortDescendants) 2874 return hitLayer; 2875 candidateLayer = hitLayer; 2876 } 2877 2878 // Now check our overflow objects. 2879 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, hitTestRect, hitTestLocation, 2880 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); 2881 if (hitLayer) { 2882 if (!depthSortDescendants) 2883 return hitLayer; 2884 candidateLayer = hitLayer; 2885 } 2886 2887 // Collect the fragments. This will compute the clip rectangles for each layer fragment. 2888 LayerFragments layerFragments; 2889 collectFragments(layerFragments, rootLayer, hitTestLocation.region(), hitTestRect, RootRelativeClipRects, IncludeOverlayScrollbarSize); 2890 2891 if (m_scrollableArea && m_scrollableArea->hitTestResizerInFragments(layerFragments, hitTestLocation)) { 2892 renderer()->updateHitTestResult(result, hitTestLocation.point()); 2893 return this; 2894 } 2895 2896 // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. Check 2897 // every fragment in reverse order. 2898 if (isSelfPaintingLayer()) { 2899 // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost. 2900 HitTestResult tempResult(result.hitTestLocation()); 2901 bool insideFragmentForegroundRect = false; 2902 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestDescendants, insideFragmentForegroundRect) 2903 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) { 2904 if (result.isRectBasedTest()) 2905 result.append(tempResult); 2906 else 2907 result = tempResult; 2908 if (!depthSortDescendants) 2909 return this; 2910 // Foreground can depth-sort with descendant layers, so keep this as a candidate. 2911 candidateLayer = this; 2912 } else if (insideFragmentForegroundRect && result.isRectBasedTest()) 2913 result.append(tempResult); 2914 } 2915 2916 // Now check our negative z-index children. 2917 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation, 2918 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); 2919 if (hitLayer) { 2920 if (!depthSortDescendants) 2921 return hitLayer; 2922 candidateLayer = hitLayer; 2923 } 2924 2925 // If we found a layer, return. Child layers, and foreground always render in front of background. 2926 if (candidateLayer) 2927 return candidateLayer; 2928 2929 if (isSelfPaintingLayer()) { 2930 HitTestResult tempResult(result.hitTestLocation()); 2931 bool insideFragmentBackgroundRect = false; 2932 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestSelf, insideFragmentBackgroundRect) 2933 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) { 2934 if (result.isRectBasedTest()) 2935 result.append(tempResult); 2936 else 2937 result = tempResult; 2938 return this; 2939 } 2940 if (insideFragmentBackgroundRect && result.isRectBasedTest()) 2941 result.append(tempResult); 2942 } 2943 2944 return 0; 2945 } 2946 2947 bool RenderLayer::hitTestContentsForFragments(const LayerFragments& layerFragments, const HitTestRequest& request, HitTestResult& result, 2948 const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& insideClipRect) const 2949 { 2950 if (layerFragments.isEmpty()) 2951 return false; 2952 2953 for (int i = layerFragments.size() - 1; i >= 0; --i) { 2954 const LayerFragment& fragment = layerFragments.at(i); 2955 if ((hitTestFilter == HitTestSelf && !fragment.backgroundRect.intersects(hitTestLocation)) 2956 || (hitTestFilter == HitTestDescendants && !fragment.foregroundRect.intersects(hitTestLocation))) 2957 continue; 2958 insideClipRect = true; 2959 if (hitTestContents(request, result, fragment.layerBounds, hitTestLocation, hitTestFilter)) 2960 return true; 2961 } 2962 2963 return false; 2964 } 2965 2966 RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result, 2967 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset) 2968 { 2969 LayerFragments enclosingPaginationFragments; 2970 LayoutPoint offsetOfPaginationLayerFromRoot; 2971 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox); 2972 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestLocation.region(), hitTestRect, 2973 RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, &transformedExtent); 2974 2975 for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) { 2976 const LayerFragment& fragment = enclosingPaginationFragments.at(i); 2977 2978 // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and 2979 // the enclosing pagination layer. 2980 LayoutRect clipRect = fragment.backgroundRect.rect(); 2981 2982 // Now compute the clips within a given fragment 2983 if (parent() != enclosingPaginationLayer()) { 2984 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot); 2985 2986 ClipRectsContext clipRectsContext(enclosingPaginationLayer(), hitTestLocation.region(), RootRelativeClipRects, IncludeOverlayScrollbarSize); 2987 LayoutRect parentClipRect = backgroundClipRect(clipRectsContext).rect(); 2988 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot); 2989 clipRect.intersect(parentClipRect); 2990 } 2991 2992 if (!hitTestLocation.intersects(clipRect)) 2993 continue; 2994 2995 RenderLayer* hitLayer = hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, 2996 transformState, zOffset, fragment.paginationOffset); 2997 if (hitLayer) 2998 return hitLayer; 2999 } 3000 3001 return 0; 3002 } 3003 3004 RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result, 3005 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset, 3006 const LayoutPoint& translationOffset) 3007 { 3008 // Create a transform state to accumulate this transform. 3009 RefPtr<HitTestingTransformState> newTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, translationOffset); 3010 3011 // If the transform can't be inverted, then don't hit test this layer at all. 3012 if (!newTransformState->m_accumulatedTransform.isInvertible()) 3013 return 0; 3014 3015 // Compute the point and the hit test rect in the coords of this layer by using the values 3016 // from the transformState, which store the point and quad in the coords of the last flattened 3017 // layer, and the accumulated transform which lets up map through preserve-3d layers. 3018 // 3019 // We can't just map hitTestLocation and hitTestRect because they may have been flattened (losing z) 3020 // by our container. 3021 FloatPoint localPoint = newTransformState->mappedPoint(); 3022 FloatQuad localPointQuad = newTransformState->mappedQuad(); 3023 LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea(); 3024 HitTestLocation newHitTestLocation; 3025 if (hitTestLocation.isRectBasedTest()) 3026 newHitTestLocation = HitTestLocation(localPoint, localPointQuad); 3027 else 3028 newHitTestLocation = HitTestLocation(localPoint); 3029 3030 // Now do a hit test with the root layer shifted to be us. 3031 return hitTestLayer(this, containerLayer, request, result, localHitTestRect, newHitTestLocation, true, newTransformState.get(), zOffset); 3032 } 3033 3034 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter) const 3035 { 3036 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); 3037 3038 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(layerBounds.location() - renderBoxLocation()), hitTestFilter)) { 3039 // It's wrong to set innerNode, but then claim that you didn't hit anything, unless it is 3040 // a rect-based test. 3041 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBasedTestResult().size())); 3042 return false; 3043 } 3044 3045 // For positioned generated content, we might still not have a 3046 // node by the time we get to the layer level, since none of 3047 // the content in the layer has an element. So just walk up 3048 // the tree. 3049 if (!result.innerNode() || !result.innerNonSharedNode()) { 3050 Node* e = enclosingElement(); 3051 if (!result.innerNode()) 3052 result.setInnerNode(e); 3053 if (!result.innerNonSharedNode()) 3054 result.setInnerNonSharedNode(e); 3055 } 3056 3057 return true; 3058 } 3059 3060 RenderLayer* RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, RenderLayer* rootLayer, 3061 const HitTestRequest& request, HitTestResult& result, 3062 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, 3063 const HitTestingTransformState* transformState, 3064 double* zOffsetForDescendants, double* zOffset, 3065 const HitTestingTransformState* unflattenedTransformState, 3066 bool depthSortDescendants) 3067 { 3068 if (!hasSelfPaintingLayerDescendant()) 3069 return 0; 3070 3071 RenderLayer* resultLayer = 0; 3072 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoVisit); 3073 while (RenderLayerStackingNode* child = iterator.next()) { 3074 RenderLayer* childLayer = child->layer(); 3075 RenderLayer* hitLayer = 0; 3076 HitTestResult tempResult(result.hitTestLocation()); 3077 if (childLayer->isPaginated()) 3078 hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request, tempResult, hitTestRect, hitTestLocation, transformState, zOffsetForDescendants); 3079 else 3080 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants); 3081 3082 // If it a rect-based test, we can safely append the temporary result since it might had hit 3083 // nodes but not necesserily had hitLayer set. 3084 if (result.isRectBasedTest()) 3085 result.append(tempResult); 3086 3087 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) { 3088 resultLayer = hitLayer; 3089 if (!result.isRectBasedTest()) 3090 result = tempResult; 3091 if (!depthSortDescendants) 3092 break; 3093 } 3094 } 3095 3096 return resultLayer; 3097 } 3098 3099 RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result, 3100 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset) 3101 { 3102 Vector<RenderLayer*> columnLayers; 3103 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContainerNode(); 3104 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) { 3105 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox())) 3106 columnLayers.append(curr); 3107 if (curr->stackingNode() == ancestorNode) 3108 break; 3109 } 3110 3111 ASSERT(columnLayers.size()); 3112 return hitTestChildLayerColumns(childLayer, rootLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset, 3113 columnLayers, columnLayers.size() - 1); 3114 } 3115 3116 RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result, 3117 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset, 3118 const Vector<RenderLayer*>& columnLayers, size_t columnIndex) 3119 { 3120 RenderBlock* columnBlock = toRenderBlock(columnLayers[columnIndex]->renderer()); 3121 3122 ASSERT(columnBlock && columnBlock->hasColumns()); 3123 if (!columnBlock || !columnBlock->hasColumns()) 3124 return 0; 3125 3126 LayoutPoint layerOffset; 3127 columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset); 3128 3129 ColumnInfo* colInfo = columnBlock->columnInfo(); 3130 int colCount = columnBlock->columnCount(colInfo); 3131 3132 // We have to go backwards from the last column to the first. 3133 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode(); 3134 LayoutUnit logicalLeft = columnBlock->logicalLeftOffsetForContent(); 3135 LayoutUnit currLogicalTopOffset = 0; 3136 int i; 3137 for (i = 0; i < colCount; i++) { 3138 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i); 3139 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width()); 3140 if (columnBlock->style()->isFlippedBlocksWritingMode()) 3141 currLogicalTopOffset += blockDelta; 3142 else 3143 currLogicalTopOffset -= blockDelta; 3144 } 3145 for (i = colCount - 1; i >= 0; i--) { 3146 // For each rect, we clip to the rect, and then we adjust our coords. 3147 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i); 3148 columnBlock->flipForWritingMode(colRect); 3149 LayoutUnit currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft; 3150 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width()); 3151 if (columnBlock->style()->isFlippedBlocksWritingMode()) 3152 currLogicalTopOffset -= blockDelta; 3153 else 3154 currLogicalTopOffset += blockDelta; 3155 3156 LayoutSize offset; 3157 if (isHorizontal) { 3158 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) 3159 offset = LayoutSize(currLogicalLeftOffset, currLogicalTopOffset); 3160 else 3161 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop()); 3162 } else { 3163 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) 3164 offset = LayoutSize(currLogicalTopOffset, currLogicalLeftOffset); 3165 else 3166 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0); 3167 } 3168 3169 colRect.moveBy(layerOffset); 3170 3171 LayoutRect localClipRect(hitTestRect); 3172 localClipRect.intersect(colRect); 3173 3174 if (!localClipRect.isEmpty() && hitTestLocation.intersects(localClipRect)) { 3175 RenderLayer* hitLayer = 0; 3176 if (!columnIndex) { 3177 // Apply a translation transform to change where the layer paints. 3178 TransformationMatrix oldTransform; 3179 bool oldHasTransform = childLayer->transform(); 3180 if (oldHasTransform) 3181 oldTransform = *childLayer->transform(); 3182 TransformationMatrix newTransform(oldTransform); 3183 newTransform.translateRight(offset.width(), offset.height()); 3184 3185 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform)); 3186 hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestLocation, false, transformState, zOffset); 3187 if (oldHasTransform) 3188 childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform)); 3189 else 3190 childLayer->m_transform.clear(); 3191 } else { 3192 // Adjust the transform such that the renderer's upper left corner will be at (0,0) in user space. 3193 // This involves subtracting out the position of the layer in our current coordinate space. 3194 RenderLayer* nextLayer = columnLayers[columnIndex - 1]; 3195 RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestLocation, transformState); 3196 newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform); 3197 FloatPoint localPoint = newTransformState->mappedPoint(); 3198 FloatQuad localPointQuad = newTransformState->mappedQuad(); 3199 LayoutRect localHitTestRect = newTransformState->mappedArea().enclosingBoundingBox(); 3200 HitTestLocation newHitTestLocation; 3201 if (hitTestLocation.isRectBasedTest()) 3202 newHitTestLocation = HitTestLocation(localPoint, localPointQuad); 3203 else 3204 newHitTestLocation = HitTestLocation(localPoint); 3205 newTransformState->flatten(); 3206 3207 hitLayer = hitTestChildLayerColumns(childLayer, columnLayers[columnIndex - 1], request, result, localHitTestRect, newHitTestLocation, 3208 newTransformState.get(), zOffset, columnLayers, columnIndex - 1); 3209 } 3210 3211 if (hitLayer) 3212 return hitLayer; 3213 } 3214 } 3215 3216 return 0; 3217 } 3218 3219 void RenderLayer::parentClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const 3220 { 3221 ASSERT(parent()); 3222 if (clipRectsContext.clipRectsType == TemporaryClipRects) { 3223 parent()->clipper().calculateClipRects(clipRectsContext, clipRects); 3224 return; 3225 } 3226 3227 parent()->m_clipper.updateClipRects(clipRectsContext); 3228 clipRects = *parent()->clipper().clipRects(clipRectsContext); 3229 } 3230 3231 static inline ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPosition position) 3232 { 3233 if (position == FixedPosition) 3234 return parentRects.fixedClipRect(); 3235 3236 if (position == AbsolutePosition) 3237 return parentRects.posClipRect(); 3238 3239 return parentRects.overflowClipRect(); 3240 } 3241 3242 ClipRect RenderLayer::backgroundClipRect(const ClipRectsContext& clipRectsContext) const 3243 { 3244 ASSERT(parent()); 3245 3246 ClipRects parentRects; 3247 3248 // If we cross into a different pagination context, then we can't rely on the cache. 3249 // Just switch over to using TemporaryClipRects. 3250 if (clipRectsContext.clipRectsType != TemporaryClipRects && parent()->enclosingPaginationLayer() != enclosingPaginationLayer()) { 3251 ClipRectsContext tempContext(clipRectsContext); 3252 tempContext.clipRectsType = TemporaryClipRects; 3253 parentClipRects(tempContext, parentRects); 3254 } else 3255 parentClipRects(clipRectsContext, parentRects); 3256 3257 ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, renderer()->style()->position()); 3258 RenderView* view = renderer()->view(); 3259 ASSERT(view); 3260 3261 // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite. 3262 if (parentRects.fixed() && clipRectsContext.rootLayer->renderer() == view && backgroundClipRect != PaintInfo::infiniteRect()) 3263 backgroundClipRect.move(view->frameView()->scrollOffsetForFixedPosition()); 3264 3265 return backgroundClipRect; 3266 } 3267 3268 void RenderLayer::calculateRects(const ClipRectsContext& clipRectsContext, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds, 3269 ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot) const 3270 { 3271 if (clipRectsContext.rootLayer != this && parent()) { 3272 backgroundRect = backgroundClipRect(clipRectsContext); 3273 backgroundRect.intersect(paintDirtyRect); 3274 } else 3275 backgroundRect = paintDirtyRect; 3276 3277 foregroundRect = backgroundRect; 3278 outlineRect = backgroundRect; 3279 3280 LayoutPoint offset; 3281 if (offsetFromRoot) 3282 offset = *offsetFromRoot; 3283 else 3284 convertToLayerCoords(clipRectsContext.rootLayer, offset); 3285 layerBounds = LayoutRect(offset, size()); 3286 3287 // Update the clip rects that will be passed to child layers. 3288 if (renderer()->hasOverflowClip()) { 3289 // This layer establishes a clip of some kind. 3290 if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip) { 3291 foregroundRect.intersect(toRenderBox(renderer())->overflowClipRect(offset, clipRectsContext.region, clipRectsContext.overlayScrollbarSizeRelevancy)); 3292 if (renderer()->style()->hasBorderRadius()) 3293 foregroundRect.setHasRadius(true); 3294 } 3295 3296 // If we establish an overflow clip at all, then go ahead and make sure our background 3297 // rect is intersected with our layer's bounds including our visual overflow, 3298 // since any visual overflow like box-shadow or border-outset is not clipped by overflow:auto/hidden. 3299 if (renderBox()->hasVisualOverflow()) { 3300 // FIXME: Perhaps we should be propagating the borderbox as the clip rect for children, even though 3301 // we may need to inflate our clip specifically for shadows or outsets. 3302 // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the 3303 // individual region boxes as overflow. 3304 LayoutRect layerBoundsWithVisualOverflow = renderBox()->visualOverflowRect(); 3305 renderBox()->flipForWritingMode(layerBoundsWithVisualOverflow); // Layers are in physical coordinates, so the overflow has to be flipped. 3306 layerBoundsWithVisualOverflow.moveBy(offset); 3307 if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip) 3308 backgroundRect.intersect(layerBoundsWithVisualOverflow); 3309 } else { 3310 // Shift the bounds to be for our region only. 3311 LayoutRect bounds = renderBox()->borderBoxRectInRegion(clipRectsContext.region); 3312 bounds.moveBy(offset); 3313 if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip) 3314 backgroundRect.intersect(bounds); 3315 } 3316 } 3317 3318 // CSS clip (different than clipping due to overflow) can clip to any box, even if it falls outside of the border box. 3319 if (renderer()->hasClip()) { 3320 // Clip applies to *us* as well, so go ahead and update the damageRect. 3321 LayoutRect newPosClip = toRenderBox(renderer())->clipRect(offset, clipRectsContext.region); 3322 backgroundRect.intersect(newPosClip); 3323 foregroundRect.intersect(newPosClip); 3324 outlineRect.intersect(newPosClip); 3325 } 3326 } 3327 3328 LayoutRect RenderLayer::childrenClipRect() const 3329 { 3330 // FIXME: border-radius not accounted for. 3331 // FIXME: Regions not accounted for. 3332 RenderView* renderView = renderer()->view(); 3333 RenderLayer* clippingRootLayer = clippingRootForPainting(); 3334 LayoutRect layerBounds; 3335 ClipRect backgroundRect, foregroundRect, outlineRect; 3336 ClipRectsContext clipRectsContext(clippingRootLayer, 0, TemporaryClipRects); 3337 // Need to use temporary clip rects, because the value of 'dontClipToOverflow' may be different from the painting path (<rdar://problem/11844909>). 3338 calculateRects(clipRectsContext, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect); 3339 return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox(); 3340 } 3341 3342 LayoutRect RenderLayer::selfClipRect() const 3343 { 3344 // FIXME: border-radius not accounted for. 3345 // FIXME: Regions not accounted for. 3346 RenderView* renderView = renderer()->view(); 3347 RenderLayer* clippingRootLayer = clippingRootForPainting(); 3348 LayoutRect layerBounds; 3349 ClipRect backgroundRect, foregroundRect, outlineRect; 3350 ClipRectsContext clipRectsContext(clippingRootLayer, 0, PaintingClipRects); 3351 calculateRects(clipRectsContext, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect); 3352 return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect.rect())).enclosingBoundingBox(); 3353 } 3354 3355 LayoutRect RenderLayer::localClipRect() const 3356 { 3357 // FIXME: border-radius not accounted for. 3358 // FIXME: Regions not accounted for. 3359 RenderLayer* clippingRootLayer = clippingRootForPainting(); 3360 LayoutRect layerBounds; 3361 ClipRect backgroundRect, foregroundRect, outlineRect; 3362 ClipRectsContext clipRectsContext(clippingRootLayer, 0, PaintingClipRects); 3363 calculateRects(clipRectsContext, PaintInfo::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect); 3364 3365 LayoutRect clipRect = backgroundRect.rect(); 3366 if (clipRect == PaintInfo::infiniteRect()) 3367 return clipRect; 3368 3369 LayoutPoint clippingRootOffset; 3370 convertToLayerCoords(clippingRootLayer, clippingRootOffset); 3371 clipRect.moveBy(-clippingRootOffset); 3372 3373 return clipRect; 3374 } 3375 3376 void RenderLayer::addBlockSelectionGapsBounds(const LayoutRect& bounds) 3377 { 3378 m_blockSelectionGapsBounds.unite(enclosingIntRect(bounds)); 3379 } 3380 3381 void RenderLayer::clearBlockSelectionGapsBounds() 3382 { 3383 m_blockSelectionGapsBounds = IntRect(); 3384 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 3385 child->clearBlockSelectionGapsBounds(); 3386 } 3387 3388 void RenderLayer::repaintBlockSelectionGaps() 3389 { 3390 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 3391 child->repaintBlockSelectionGaps(); 3392 3393 if (m_blockSelectionGapsBounds.isEmpty()) 3394 return; 3395 3396 LayoutRect rect = m_blockSelectionGapsBounds; 3397 if (renderer()->hasOverflowClip()) { 3398 RenderBox* box = renderBox(); 3399 rect.move(-box->scrolledContentOffset()); 3400 if (!scrollableArea()->usesCompositedScrolling()) 3401 rect.intersect(box->overflowClipRect(LayoutPoint(), 0)); // FIXME: Regions not accounted for. 3402 } 3403 if (renderer()->hasClip()) 3404 rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint(), 0)); // FIXME: Regions not accounted for. 3405 if (!rect.isEmpty()) 3406 renderer()->repaintRectangle(rect); 3407 } 3408 3409 bool RenderLayer::hasBlockSelectionGapBounds() const 3410 { 3411 return !m_blockSelectionGapsBounds.isEmpty(); 3412 } 3413 3414 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot) const 3415 { 3416 // Always examine the canvas and the root. 3417 // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView 3418 // paints the root's background. 3419 if (isRootLayer() || renderer()->isRoot()) 3420 return true; 3421 3422 // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we 3423 // can go ahead and return true. 3424 RenderView* view = renderer()->view(); 3425 ASSERT(view); 3426 if (view && !renderer()->isRenderInline()) { 3427 LayoutRect b = layerBounds; 3428 b.inflate(view->maximalOutlineSize()); 3429 if (b.intersects(damageRect)) 3430 return true; 3431 } 3432 3433 // Otherwise we need to compute the bounding box of this single layer and see if it intersects 3434 // the damage rect. 3435 return boundingBox(rootLayer, 0, offsetFromRoot).intersects(damageRect); 3436 } 3437 3438 LayoutRect RenderLayer::localBoundingBox(CalculateLayerBoundsFlags flags) const 3439 { 3440 // There are three special cases we need to consider. 3441 // (1) Inline Flows. For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the 3442 // inline. In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the 3443 // line boxes of all three lines (including overflow on those lines). 3444 // (2) Left/Top Overflow. The width/height of layers already includes right/bottom overflow. However, in the case of left/top 3445 // overflow, we have to create a bounding box that will extend to include this overflow. 3446 // (3) Floats. When a layer has overhanging floats that it paints, we need to make sure to include these overhanging floats 3447 // as part of our bounding box. We do this because we are the responsible layer for both hit testing and painting those 3448 // floats. 3449 LayoutRect result; 3450 if (renderer()->isInline() && renderer()->isRenderInline()) 3451 result = toRenderInline(renderer())->linesVisualOverflowBoundingBox(); 3452 else if (renderer()->isTableRow()) { 3453 // Our bounding box is just the union of all of our cells' border/overflow rects. 3454 for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) { 3455 if (child->isTableCell()) { 3456 LayoutRect bbox = toRenderBox(child)->borderBoxRect(); 3457 result.unite(bbox); 3458 LayoutRect overflowRect = renderBox()->visualOverflowRect(); 3459 if (bbox != overflowRect) 3460 result.unite(overflowRect); 3461 } 3462 } 3463 } else { 3464 RenderBox* box = renderBox(); 3465 ASSERT(box); 3466 if (!(flags & DontConstrainForMask) && box->hasMask()) { 3467 result = box->maskClipRect(); 3468 box->flipForWritingMode(result); // The mask clip rect is in physical coordinates, so we have to flip, since localBoundingBox is not. 3469 } else { 3470 LayoutRect bbox = box->borderBoxRect(); 3471 result = bbox; 3472 LayoutRect overflowRect = box->visualOverflowRect(); 3473 if (bbox != overflowRect) 3474 result.unite(overflowRect); 3475 } 3476 } 3477 3478 RenderView* view = renderer()->view(); 3479 ASSERT(view); 3480 if (view) 3481 result.inflate(view->maximalOutlineSize()); // Used to apply a fudge factor to dirty-rect checks on blocks/tables. 3482 3483 return result; 3484 } 3485 3486 LayoutRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer, CalculateLayerBoundsFlags flags, const LayoutPoint* offsetFromRoot) const 3487 { 3488 LayoutRect result = localBoundingBox(flags); 3489 if (renderer()->isBox()) 3490 renderBox()->flipForWritingMode(result); 3491 else 3492 renderer()->containingBlock()->flipForWritingMode(result); 3493 3494 if (enclosingPaginationLayer() && (flags & UseFragmentBoxes)) { 3495 // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to 3496 // get our true bounding box. 3497 LayoutPoint offsetWithinPaginationLayer; 3498 convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginationLayer); 3499 result.moveBy(offsetWithinPaginationLayer); 3500 3501 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer()); 3502 result = enclosingFlowThread->fragmentsBoundingBox(result); 3503 3504 LayoutPoint delta; 3505 if (offsetFromRoot) 3506 delta = *offsetFromRoot; 3507 else 3508 enclosingPaginationLayer()->convertToLayerCoords(ancestorLayer, delta); 3509 result.moveBy(delta); 3510 return result; 3511 } 3512 3513 LayoutPoint delta; 3514 if (offsetFromRoot) 3515 delta = *offsetFromRoot; 3516 else 3517 convertToLayerCoords(ancestorLayer, delta); 3518 3519 result.moveBy(delta); 3520 return result; 3521 } 3522 3523 IntRect RenderLayer::absoluteBoundingBox() const 3524 { 3525 return pixelSnappedIntRect(boundingBox(root())); 3526 } 3527 3528 IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot, CalculateLayerBoundsFlags flags) const 3529 { 3530 if (!isSelfPaintingLayer()) 3531 return IntRect(); 3532 3533 // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580). 3534 if ((flags & ExcludeHiddenDescendants) && this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant()) 3535 return IntRect(); 3536 3537 RenderLayerModelObject* renderer = this->renderer(); 3538 3539 if (isRootLayer()) { 3540 // The root layer is always just the size of the document. 3541 return renderer->view()->unscaledDocumentRect(); 3542 } 3543 3544 LayoutRect boundingBoxRect = localBoundingBox(flags); 3545 3546 if (renderer->isBox()) 3547 toRenderBox(renderer)->flipForWritingMode(boundingBoxRect); 3548 else 3549 renderer->containingBlock()->flipForWritingMode(boundingBoxRect); 3550 3551 if (renderer->isRoot()) { 3552 // If the root layer becomes composited (e.g. because some descendant with negative z-index is composited), 3553 // then it has to be big enough to cover the viewport in order to display the background. This is akin 3554 // to the code in RenderBox::paintRootBoxFillLayers(). 3555 if (FrameView* frameView = renderer->view()->frameView()) { 3556 LayoutUnit contentsWidth = frameView->contentsWidth(); 3557 LayoutUnit contentsHeight = frameView->contentsHeight(); 3558 3559 boundingBoxRect.setWidth(max(boundingBoxRect.width(), contentsWidth - boundingBoxRect.x())); 3560 boundingBoxRect.setHeight(max(boundingBoxRect.height(), contentsHeight - boundingBoxRect.y())); 3561 } 3562 } 3563 3564 LayoutRect unionBounds = boundingBoxRect; 3565 bool shouldIncludeTransform = paintsWithTransform(PaintBehaviorNormal) || (transform() && flags & PretendLayerHasOwnBacking); 3566 3567 if (flags & UseLocalClipRectIfPossible) { 3568 LayoutRect localClipRect = this->localClipRect(); 3569 if (localClipRect != PaintInfo::infiniteRect()) { 3570 if ((flags & IncludeSelfTransform) && shouldIncludeTransform) 3571 localClipRect = transform()->mapRect(localClipRect); 3572 3573 LayoutPoint ancestorRelOffset; 3574 convertToLayerCoords(ancestorLayer, ancestorRelOffset); 3575 localClipRect.moveBy(ancestorRelOffset); 3576 return pixelSnappedIntRect(localClipRect); 3577 } 3578 } 3579 3580 // FIXME: should probably just pass 'flags' down to descendants. 3581 CalculateLayerBoundsFlags descendantFlags = DefaultCalculateLayerBoundsFlags | (flags & ExcludeHiddenDescendants) | (flags & IncludeCompositedDescendants); 3582 3583 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded(); 3584 3585 if (m_reflectionInfo) { 3586 RenderLayer* reflectionLayer = m_reflectionInfo->reflectionLayer(); 3587 if (!reflectionLayer->hasCompositedLayerMapping()) { 3588 IntRect childUnionBounds = reflectionLayer->calculateLayerBounds(this, 0, descendantFlags); 3589 unionBounds.unite(childUnionBounds); 3590 } 3591 } 3592 3593 ASSERT(m_stackingNode->isStackingContainer() || !m_stackingNode->hasPositiveZOrderList()); 3594 3595 #if !ASSERT_DISABLED 3596 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(this)->stackingNode()); 3597 #endif 3598 3599 // FIXME: Descendants that are composited should not necessarily be skipped, if they don't paint into their own 3600 // separate backing. Instead, they ought to contribute to the bounds of the layer we're trying to compute. 3601 // This applies to all z-order lists below. 3602 RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), AllChildren); 3603 while (RenderLayerStackingNode* node = iterator.next()) { 3604 // Node's compositing ancestor may have changed its draw content status 3605 // prior to updating its bounds. The requires-own-backing-store-for-ancestor-reasons 3606 // could be stale. Refresh them now. 3607 if (node->layer()->hasCompositedLayerMapping()) { 3608 RenderLayer* enclosingCompositingLayer = node->layer()->enclosingCompositingLayer(false); 3609 node->layer()->compositedLayerMapping()->updateRequiresOwnBackingStoreForAncestorReasons(enclosingCompositingLayer); 3610 } 3611 3612 if (flags & IncludeCompositedDescendants || !node->layer()->hasCompositedLayerMapping()) { 3613 IntRect childUnionBounds = node->layer()->calculateLayerBounds(this, 0, descendantFlags); 3614 unionBounds.unite(childUnionBounds); 3615 } 3616 } 3617 3618 // FIXME: We can optimize the size of the composited layers, by not enlarging 3619 // filtered areas with the outsets if we know that the filter is going to render in hardware. 3620 // https://bugs.webkit.org/show_bug.cgi?id=81239 3621 if (flags & IncludeLayerFilterOutsets) 3622 renderer->style()->filterOutsets().expandRect(unionBounds); 3623 3624 if ((flags & IncludeSelfTransform) && shouldIncludeTransform) { 3625 TransformationMatrix* affineTrans = transform(); 3626 boundingBoxRect = affineTrans->mapRect(boundingBoxRect); 3627 unionBounds = affineTrans->mapRect(unionBounds); 3628 } 3629 3630 LayoutPoint ancestorRelOffset; 3631 if (offsetFromRoot) 3632 ancestorRelOffset = *offsetFromRoot; 3633 else 3634 convertToLayerCoords(ancestorLayer, ancestorRelOffset); 3635 unionBounds.moveBy(ancestorRelOffset); 3636 3637 return pixelSnappedIntRect(unionBounds); 3638 } 3639 3640 CompositingState RenderLayer::compositingState() const 3641 { 3642 // This is computed procedurally so there is no redundant state variable that 3643 // can get out of sync from the real actual compositing state. 3644 3645 if (m_groupedMapping) { 3646 ASSERT(compositor()->layerSquashingEnabled()); 3647 ASSERT(!m_compositedLayerMapping); 3648 return PaintsIntoGroupedBacking; 3649 } 3650 3651 if (!m_compositedLayerMapping) 3652 return NotComposited; 3653 3654 if (m_compositedLayerMapping && compositedLayerMapping()->paintsIntoCompositedAncestor()) 3655 return HasOwnBackingButPaintsIntoAncestor; 3656 3657 ASSERT(m_compositedLayerMapping); 3658 return PaintsIntoOwnBacking; 3659 } 3660 3661 CompositedLayerMappingPtr RenderLayer::ensureCompositedLayerMapping() 3662 { 3663 if (!m_compositedLayerMapping) { 3664 m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(this)); 3665 3666 updateOrRemoveFilterEffectRenderer(); 3667 3668 if (RuntimeEnabledFeatures::cssCompositingEnabled()) 3669 compositedLayerMapping()->setBlendMode(m_blendMode); 3670 } 3671 return m_compositedLayerMapping.get(); 3672 } 3673 3674 void RenderLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) 3675 { 3676 m_compositedLayerMapping.clear(); 3677 3678 if (!layerBeingDestroyed) 3679 updateOrRemoveFilterEffectRenderer(); 3680 } 3681 3682 bool RenderLayer::hasCompositedMask() const 3683 { 3684 return m_compositedLayerMapping && m_compositedLayerMapping->hasMaskLayer(); 3685 } 3686 3687 bool RenderLayer::hasCompositedClippingMask() const 3688 { 3689 return m_compositedLayerMapping && m_compositedLayerMapping->hasChildClippingMaskLayer(); 3690 } 3691 3692 bool RenderLayer::clipsCompositingDescendantsWithBorderRadius() const 3693 { 3694 RenderStyle* style = renderer()->style(); 3695 if (!style) 3696 return false; 3697 3698 return compositor()->clipsCompositingDescendants(this) && style->hasBorderRadius(); 3699 } 3700 3701 bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const 3702 { 3703 return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || compositingState() != PaintsIntoOwnBacking); 3704 } 3705 3706 bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const 3707 { 3708 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) 3709 return false; 3710 3711 if (paintsWithTransparency(PaintBehaviorNormal)) 3712 return false; 3713 3714 // We can't use hasVisibleContent(), because that will be true if our renderer is hidden, but some child 3715 // is visible and that child doesn't cover the entire rect. 3716 if (renderer()->style()->visibility() != VISIBLE) 3717 return false; 3718 3719 if (paintsWithFilters() && renderer()->style()->filter().hasFilterThatAffectsOpacity()) 3720 return false; 3721 3722 // FIXME: Handle simple transforms. 3723 if (paintsWithTransform(PaintBehaviorNormal)) 3724 return false; 3725 3726 // FIXME: Remove this check. 3727 // This function should not be called when layer-lists are dirty. 3728 // It is somehow getting triggered during style update. 3729 if (m_stackingNode->zOrderListsDirty() || m_stackingNode->normalFlowListDirty()) 3730 return false; 3731 3732 // FIXME: We currently only check the immediate renderer, 3733 // which will miss many cases. 3734 if (renderer()->backgroundIsKnownToBeOpaqueInRect(localRect)) 3735 return true; 3736 3737 // We can't consult child layers if we clip, since they might cover 3738 // parts of the rect that are clipped out. 3739 if (renderer()->hasOverflowClip()) 3740 return false; 3741 3742 return childBackgroundIsKnownToBeOpaqueInRect(localRect); 3743 } 3744 3745 bool RenderLayer::childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const 3746 { 3747 RenderLayerStackingNodeReverseIterator revertseIterator(*m_stackingNode, PositiveZOrderChildren | NormalFlowChildren | NegativeZOrderChildren); 3748 while (RenderLayerStackingNode* child = revertseIterator.next()) { 3749 const RenderLayer* childLayer = child->layer(); 3750 if (childLayer->hasCompositedLayerMapping()) 3751 continue; 3752 3753 if (!childLayer->canUseConvertToLayerCoords()) 3754 continue; 3755 3756 LayoutPoint childOffset; 3757 LayoutRect childLocalRect(localRect); 3758 childLayer->convertToLayerCoords(this, childOffset); 3759 childLocalRect.moveBy(-childOffset); 3760 3761 if (childLayer->backgroundIsKnownToBeOpaqueInRect(childLocalRect)) 3762 return true; 3763 } 3764 return false; 3765 } 3766 3767 void RenderLayer::setParent(RenderLayer* parent) 3768 { 3769 if (parent == m_parent) 3770 return; 3771 3772 if (m_parent && !renderer()->documentBeingDestroyed()) 3773 compositor()->layerWillBeRemoved(m_parent, this); 3774 3775 m_parent = parent; 3776 3777 if (m_parent && !renderer()->documentBeingDestroyed()) 3778 compositor()->layerWasAdded(m_parent, this); 3779 } 3780 3781 bool RenderLayer::shouldBeSelfPaintingLayer() const 3782 { 3783 return !m_stackingNode->isNormalFlowOnly() 3784 || (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars()) 3785 || needsCompositedScrolling() 3786 || renderer()->hasReflection() 3787 || renderer()->hasMask() 3788 || renderer()->isTableRow() 3789 || renderer()->isCanvas() 3790 || renderer()->isVideo() 3791 || renderer()->isEmbeddedObject() 3792 || renderer()->isRenderIFrame(); 3793 } 3794 3795 void RenderLayer::updateSelfPaintingLayer() 3796 { 3797 bool isSelfPaintingLayer = this->shouldBeSelfPaintingLayer(); 3798 if (this->isSelfPaintingLayer() == isSelfPaintingLayer) 3799 return; 3800 3801 m_isSelfPaintingLayer = isSelfPaintingLayer; 3802 if (!parent()) 3803 return; 3804 if (isSelfPaintingLayer) 3805 parent()->setAncestorChainHasSelfPaintingLayerDescendant(); 3806 else 3807 parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 3808 } 3809 3810 bool RenderLayer::hasNonEmptyChildRenderers() const 3811 { 3812 // Some HTML can cause whitespace text nodes to have renderers, like: 3813 // <div> 3814 // <img src=...> 3815 // </div> 3816 // so test for 0x0 RenderTexts here 3817 for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) { 3818 if (!child->hasLayer()) { 3819 if (child->isRenderInline() || !child->isBox()) 3820 return true; 3821 3822 if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0) 3823 return true; 3824 } 3825 } 3826 return false; 3827 } 3828 3829 static bool hasBoxDecorations(const RenderStyle* style) 3830 { 3831 return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter(); 3832 } 3833 3834 bool RenderLayer::hasBoxDecorationsOrBackground() const 3835 { 3836 return hasBoxDecorations(renderer()->style()) || renderer()->hasBackground(); 3837 } 3838 3839 bool RenderLayer::hasVisibleBoxDecorations() const 3840 { 3841 if (!hasVisibleContent()) 3842 return false; 3843 3844 return hasBoxDecorationsOrBackground() || hasOverflowControls(); 3845 } 3846 3847 bool RenderLayer::isVisuallyNonEmpty() const 3848 { 3849 ASSERT(!m_visibleDescendantStatusDirty); 3850 3851 if (hasVisibleContent() && hasNonEmptyChildRenderers()) 3852 return true; 3853 3854 if (renderer()->isReplaced() || renderer()->hasMask()) 3855 return true; 3856 3857 if (hasVisibleBoxDecorations()) 3858 return true; 3859 3860 return false; 3861 } 3862 3863 void RenderLayer::updateVisibilityAfterStyleChange(const RenderStyle* oldStyle) 3864 { 3865 if (!oldStyle || (oldStyle->visibility() != renderer()->style()->visibility())) 3866 compositor()->setNeedsUpdateCompositingRequirementsState(); 3867 } 3868 3869 void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle) 3870 { 3871 if (oldStyle && (renderer()->style()->position() == oldStyle->position())) 3872 return; 3873 3874 bool wasOutOfFlowPositioned = oldStyle && (oldStyle->position() == AbsolutePosition || oldStyle->position() == FixedPosition); 3875 bool isOutOfFlowPositioned = renderer()->isOutOfFlowPositioned(); 3876 if (!wasOutOfFlowPositioned && !isOutOfFlowPositioned) 3877 return; 3878 3879 // Even if the layer remains out-of-flow, a change to this property 3880 // will likely change its containing block. We must clear these bits 3881 // so that they can be set properly by the RenderLayerCompositor. 3882 for (RenderLayer* ancestor = parent(); ancestor; ancestor = ancestor->parent()) 3883 ancestor->setHasUnclippedDescendant(false); 3884 3885 // Ensures that we reset the above bits correctly. 3886 compositor()->setNeedsUpdateCompositingRequirementsState(); 3887 3888 if (wasOutOfFlowPositioned && isOutOfFlowPositioned) 3889 return; 3890 3891 if (isOutOfFlowPositioned) { 3892 setAncestorChainHasOutOfFlowPositionedDescendant(); 3893 compositor()->addOutOfFlowPositionedLayer(this); 3894 } else { 3895 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 3896 compositor()->removeOutOfFlowPositionedLayer(this); 3897 3898 // We need to reset the isUnclippedDescendant bit here because normally 3899 // the "unclipped-ness" property is only updated in 3900 // RenderLayerCompositor::updateCompositingRequirementsState(). However, 3901 // it is only updated for layers which are known to be out of flow. 3902 // Since this is no longer out of flow, we have to explicitly ensure 3903 // that it doesn't think it is unclipped. 3904 setIsUnclippedDescendant(false); 3905 } 3906 } 3907 3908 static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle) 3909 { 3910 ASSERT(newStyle); 3911 return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter(); 3912 } 3913 3914 inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const 3915 { 3916 ASSERT(newStyle); 3917 return oldStyle && (oldStyle->clip() != newStyle->clip() || oldStyle->hasClip() != newStyle->hasClip()); 3918 } 3919 3920 inline bool RenderLayer::needsCompositingLayersRebuiltForOverflow(const RenderStyle* oldStyle, const RenderStyle* newStyle) const 3921 { 3922 ASSERT(newStyle); 3923 return !hasCompositedLayerMapping() && oldStyle && (oldStyle->overflowX() != newStyle->overflowX()) && m_stackingNode->ancestorStackingContainerNode()->layer()->hasCompositingDescendant(); 3924 } 3925 3926 inline bool RenderLayer::needsCompositingLayersRebuiltForFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle, bool didPaintWithFilters) const 3927 { 3928 if (!hasOrHadFilters(oldStyle, newStyle)) 3929 return false; 3930 3931 if (RuntimeEnabledFeatures::webAnimationsCSSEnabled() 3932 ? hasActiveAnimationsOnCompositor(*renderer(), CSSPropertyWebkitFilter) 3933 : renderer()->animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitFilter)) { 3934 3935 // When the compositor is performing the filter animation, we shouldn't touch the compositing layers. 3936 // All of the layers above us should have been promoted to compositing layers already. 3937 return false; 3938 } 3939 3940 FilterOutsets newOutsets = newStyle->filterOutsets(); 3941 if (oldStyle && (oldStyle->filterOutsets() != newOutsets)) { 3942 // When filter outsets change, we need to: 3943 // (1) Recompute the overlap map to promote the correct layers to composited layers. 3944 // (2) Update the composited layer bounds (and child GraphicsLayer positions) on platforms 3945 // whose compositors can't compute their own filter outsets. 3946 return true; 3947 } 3948 3949 #if HAVE(COMPOSITOR_FILTER_OUTSETS) 3950 if ((didPaintWithFilters != paintsWithFilters()) && !newOutsets.isZero()) { 3951 // When the layer used to paint filters in software and now paints filters in the 3952 // compositor, the compositing layer bounds need to change from including filter outsets to 3953 // excluding filter outsets, on platforms whose compositors compute their own outsets. 3954 // Similarly for the reverse change from compositor-painted to software-painted filters. 3955 return true; 3956 } 3957 #endif 3958 3959 return false; 3960 } 3961 3962 inline bool RenderLayer::needsCompositingLayersRebuiltForBlending(const RenderStyle* oldStyle, const RenderStyle* newStyle) const 3963 { 3964 ASSERT(newStyle); 3965 if (!hasCompositedLayerMapping()) 3966 return false; 3967 return (shouldIsolateCompositedDescendants() && !stackingNode()->isStackingContext()) 3968 || (oldStyle && (oldStyle->hasBlendMode() != newStyle->hasBlendMode())); 3969 } 3970 3971 void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle) 3972 { 3973 if (!hasOrHadFilters(oldStyle, newStyle)) 3974 return; 3975 3976 updateOrRemoveFilterClients(); 3977 // During an accelerated animation, both WebKit and the compositor animate properties. 3978 // However, WebKit shouldn't ask the compositor to update its filters if the compositor is performing the animation. 3979 if (hasCompositedLayerMapping() && (RuntimeEnabledFeatures::webAnimationsCSSEnabled() 3980 ? !hasActiveAnimationsOnCompositor(*renderer(), CSSPropertyWebkitFilter) 3981 : !renderer()->animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitFilter))) 3982 compositedLayerMapping()->updateFilters(renderer()->style()); 3983 updateOrRemoveFilterEffectRenderer(); 3984 } 3985 3986 void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle) 3987 { 3988 m_stackingNode->updateIsNormalFlowOnly(); 3989 3990 if (m_scrollableArea) 3991 m_scrollableArea->updateAfterStyleChange(oldStyle); 3992 m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle); 3993 updateVisibilityAfterStyleChange(oldStyle); 3994 // Overlay scrollbars can make this layer self-painting so we need 3995 // to recompute the bit once scrollbars have been updated. 3996 updateSelfPaintingLayer(); 3997 updateOutOfFlowPositioned(oldStyle); 3998 3999 updateReflectionInfo(oldStyle); 4000 4001 if (RuntimeEnabledFeatures::cssCompositingEnabled()) 4002 updateBlendMode(); 4003 4004 updateDescendantDependentFlags(); 4005 updateTransform(); 4006 4007 bool didPaintWithFilters = false; 4008 4009 if (paintsWithFilters()) 4010 didPaintWithFilters = true; 4011 updateFilters(oldStyle, renderer()->style()); 4012 4013 const RenderStyle* newStyle = renderer()->style(); 4014 if (compositor()->updateLayerCompositingState(this) 4015 || needsCompositingLayersRebuiltForClip(oldStyle, newStyle) 4016 || needsCompositingLayersRebuiltForOverflow(oldStyle, newStyle) 4017 || needsCompositingLayersRebuiltForFilters(oldStyle, newStyle, didPaintWithFilters) 4018 || needsCompositingLayersRebuiltForBlending(oldStyle, newStyle)) { 4019 compositor()->setCompositingLayersNeedRebuild(); 4020 } else if (compositingState() == PaintsIntoOwnBacking || compositingState() == HasOwnBackingButPaintsIntoAncestor) { 4021 ASSERT(hasCompositedLayerMapping()); 4022 compositedLayerMapping()->updateGraphicsLayerGeometry(); 4023 } else if (compositingState() == PaintsIntoGroupedBacking) { 4024 ASSERT(compositor()->layerSquashingEnabled()); 4025 ASSERT(groupedMapping()); 4026 // updateGraphicsLayerGeometry() is called to update the squashingLayer in case its size/position has changed. 4027 // FIXME: Make sure to create a layout test that covers this scenario. 4028 // FIXME: It is not expected that any other layers on the compositedLayerMapping would change. we should 4029 // be able to just update the squashing layer only and save a lot of computation. 4030 groupedMapping()->updateGraphicsLayerGeometry(); 4031 } 4032 } 4033 4034 bool RenderLayer::scrollsOverflow() const 4035 { 4036 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea()) 4037 return scrollableArea->scrollsOverflow(); 4038 4039 return false; 4040 } 4041 4042 bool RenderLayer::isCSSCustomFilterEnabled() const 4043 { 4044 // We only want to enable shaders if WebGL is also enabled on this platform. 4045 const Settings* settings = renderer()->document().settings(); 4046 return settings && RuntimeEnabledFeatures::cssCustomFilterEnabled() && settings->webGLEnabled(); 4047 } 4048 4049 FilterOperations RenderLayer::computeFilterOperations(const RenderStyle* style) 4050 { 4051 const FilterOperations& filters = style->filter(); 4052 if (filters.hasReferenceFilter()) { 4053 for (size_t i = 0; i < filters.size(); ++i) { 4054 FilterOperation* filterOperation = filters.operations().at(i).get(); 4055 if (filterOperation->type() != FilterOperation::REFERENCE) 4056 continue; 4057 ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation); 4058 // FIXME: Cache the ReferenceFilter if it didn't change. 4059 RefPtr<ReferenceFilter> referenceFilter = ReferenceFilter::create(); 4060 float zoom = style->effectiveZoom() * WebCore::deviceScaleFactor(renderer()->frame()); 4061 referenceFilter->setFilterResolution(FloatSize(zoom, zoom)); 4062 referenceFilter->setLastEffect(ReferenceFilterBuilder::build(referenceFilter.get(), renderer(), referenceFilter->sourceGraphic(), 4063 referenceOperation)); 4064 referenceOperation->setFilter(referenceFilter.release()); 4065 } 4066 } 4067 4068 if (!filters.hasCustomFilter()) 4069 return filters; 4070 4071 if (!isCSSCustomFilterEnabled()) { 4072 // CSS Custom filters should not parse at all in this case, but there might be 4073 // remaining styles that were parsed when the flag was enabled. Reproduces in DumpRenderTree 4074 // because it resets the flag while the previous test is still loaded. 4075 return FilterOperations(); 4076 } 4077 4078 FilterOperations outputFilters; 4079 for (size_t i = 0; i < filters.size(); ++i) { 4080 RefPtr<FilterOperation> filterOperation = filters.operations().at(i); 4081 if (filterOperation->type() == FilterOperation::CUSTOM) { 4082 // We have to wait until the program of CSS Shaders is loaded before setting it on the layer. 4083 // Note that we will handle the loading of the shaders and repainting of the layer in updateOrRemoveFilterClients. 4084 const CustomFilterOperation* customOperation = toCustomFilterOperation(filterOperation.get()); 4085 RefPtr<CustomFilterProgram> program = customOperation->program(); 4086 if (!program->isLoaded()) 4087 continue; 4088 4089 CustomFilterGlobalContext* globalContext = renderer()->view()->customFilterGlobalContext(); 4090 RefPtr<CustomFilterValidatedProgram> validatedProgram = globalContext->getValidatedProgram(program->programInfo()); 4091 if (!validatedProgram->isInitialized()) 4092 continue; 4093 4094 RefPtr<ValidatedCustomFilterOperation> validatedOperation = ValidatedCustomFilterOperation::create(validatedProgram.release(), 4095 customOperation->parameters(), customOperation->meshRows(), customOperation->meshColumns(), customOperation->meshType()); 4096 outputFilters.operations().append(validatedOperation.release()); 4097 continue; 4098 } 4099 outputFilters.operations().append(filterOperation.release()); 4100 } 4101 return outputFilters; 4102 } 4103 4104 void RenderLayer::updateOrRemoveFilterClients() 4105 { 4106 if (!hasFilter()) { 4107 removeFilterInfoIfNeeded(); 4108 return; 4109 } 4110 4111 if (renderer()->style()->filter().hasCustomFilter()) 4112 ensureFilterInfo()->updateCustomFilterClients(renderer()->style()->filter()); 4113 else if (hasFilterInfo()) 4114 filterInfo()->removeCustomFilterClients(); 4115 4116 if (renderer()->style()->filter().hasReferenceFilter()) 4117 ensureFilterInfo()->updateReferenceFilterClients(renderer()->style()->filter()); 4118 else if (hasFilterInfo()) 4119 filterInfo()->removeReferenceFilterClients(); 4120 } 4121 4122 void RenderLayer::updateOrRemoveFilterEffectRenderer() 4123 { 4124 // FilterEffectRenderer is only used to render the filters in software mode, 4125 // so we always need to run updateOrRemoveFilterEffectRenderer after the composited 4126 // mode might have changed for this layer. 4127 if (!paintsWithFilters()) { 4128 // Don't delete the whole filter info here, because we might use it 4129 // for loading CSS shader files. 4130 if (RenderLayerFilterInfo* filterInfo = this->filterInfo()) 4131 filterInfo->setRenderer(0); 4132 4133 return; 4134 } 4135 4136 RenderLayerFilterInfo* filterInfo = ensureFilterInfo(); 4137 if (!filterInfo->renderer()) { 4138 RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create(); 4139 filterRenderer->setIsAccelerated(renderer()->frame()->settings()->acceleratedFiltersEnabled()); 4140 filterInfo->setRenderer(filterRenderer.release()); 4141 4142 // We can optimize away code paths in other places if we know that there are no software filters. 4143 renderer()->document().view()->setHasSoftwareFilters(true); 4144 } 4145 4146 // If the filter fails to build, remove it from the layer. It will still attempt to 4147 // go through regular processing (e.g. compositing), but never apply anything. 4148 if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(renderer()->style()))) 4149 filterInfo->setRenderer(0); 4150 } 4151 4152 void RenderLayer::filterNeedsRepaint() 4153 { 4154 toElement(renderer()->node())->scheduleLayerUpdate(); 4155 if (renderer()->view()) 4156 renderer()->repaint(); 4157 } 4158 4159 void RenderLayer::addLayerHitTestRects(LayerHitTestRects& rects) const 4160 { 4161 if (!size().isEmpty()) { 4162 Vector<LayoutRect> rect; 4163 4164 if (renderBox() && renderBox()->scrollsOverflow()) { 4165 // For scrolling layers, rects are taken to be in the space of the contents. 4166 // We need to include both the entire contents, and also the bounding box 4167 // of the layer in the space of it's parent (eg. for border / scroll bars). 4168 rect.append(m_scrollableArea->overflowRect()); 4169 rects.set(this, rect); 4170 if (const RenderLayer* parentLayer = parent()) { 4171 LayerHitTestRects::iterator iter = rects.find(parentLayer); 4172 if (iter == rects.end()) 4173 iter = rects.add(parentLayer, Vector<LayoutRect>()).iterator; 4174 iter->value.append(boundingBox(parentLayer)); 4175 } 4176 } else { 4177 rect.append(localBoundingBox()); 4178 rects.set(this, rect); 4179 } 4180 } 4181 4182 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 4183 child->addLayerHitTestRects(rects); 4184 } 4185 4186 } // namespace WebCore 4187 4188 #ifndef NDEBUG 4189 void showLayerTree(const WebCore::RenderLayer* layer) 4190 { 4191 if (!layer) 4192 return; 4193 4194 if (WebCore::Frame* frame = layer->renderer()->frame()) { 4195 WTF::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers | WebCore::RenderAsTextShowAddresses | WebCore::RenderAsTextShowIDAndClass | WebCore::RenderAsTextDontUpdateLayout | WebCore::RenderAsTextShowLayoutState); 4196 fprintf(stderr, "%s\n", output.utf8().data()); 4197 } 4198 } 4199 4200 void showLayerTree(const WebCore::RenderObject* renderer) 4201 { 4202 if (!renderer) 4203 return; 4204 showLayerTree(renderer->enclosingLayer()); 4205 } 4206 #endif 4207