1 /* 2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 28 #include "core/rendering/RenderLayerCompositor.h" 29 30 #include "CSSPropertyNames.h" 31 #include "HTMLNames.h" 32 #include "RuntimeEnabledFeatures.h" 33 #include "core/animation/ActiveAnimations.h" 34 #include "core/animation/DocumentAnimations.h" 35 #include "core/dom/FullscreenElementStack.h" 36 #include "core/dom/NodeList.h" 37 #include "core/html/HTMLCanvasElement.h" 38 #include "core/html/HTMLIFrameElement.h" 39 #include "core/html/HTMLVideoElement.h" 40 #include "core/html/canvas/CanvasRenderingContext.h" 41 #include "core/inspector/InspectorInstrumentation.h" 42 #include "core/page/Chrome.h" 43 #include "core/frame/Frame.h" 44 #include "core/frame/FrameView.h" 45 #include "core/page/Page.h" 46 #include "core/frame/Settings.h" 47 #include "core/frame/animation/AnimationController.h" 48 #include "core/page/scrolling/ScrollingConstraints.h" 49 #include "core/page/scrolling/ScrollingCoordinator.h" 50 #include "core/rendering/CompositedLayerMapping.h" 51 #include "core/rendering/HitTestResult.h" 52 #include "core/rendering/RenderApplet.h" 53 #include "core/rendering/RenderEmbeddedObject.h" 54 #include "core/rendering/RenderFullScreen.h" 55 #include "core/rendering/RenderGeometryMap.h" 56 #include "core/rendering/RenderIFrame.h" 57 #include "core/rendering/RenderLayerStackingNode.h" 58 #include "core/rendering/RenderLayerStackingNodeIterator.h" 59 #include "core/rendering/RenderReplica.h" 60 #include "core/rendering/RenderVideo.h" 61 #include "core/rendering/RenderView.h" 62 #include "platform/OverscrollTheme.h" 63 #include "platform/TraceEvent.h" 64 #include "platform/geometry/TransformState.h" 65 #include "platform/graphics/GraphicsLayer.h" 66 #include "platform/scroll/ScrollbarTheme.h" 67 #include "public/platform/Platform.h" 68 #include "wtf/TemporaryChange.h" 69 70 #ifndef NDEBUG 71 #include "core/rendering/RenderTreeAsText.h" 72 #endif 73 74 namespace WebCore { 75 76 using namespace HTMLNames; 77 78 class OverlapMapContainer { 79 public: 80 void add(const IntRect& bounds) 81 { 82 m_layerRects.append(bounds); 83 m_boundingBox.unite(bounds); 84 } 85 86 bool overlapsLayers(const IntRect& bounds) const 87 { 88 // Checking with the bounding box will quickly reject cases when 89 // layers are created for lists of items going in one direction and 90 // never overlap with each other. 91 if (!bounds.intersects(m_boundingBox)) 92 return false; 93 for (unsigned i = 0; i < m_layerRects.size(); i++) { 94 if (m_layerRects[i].intersects(bounds)) 95 return true; 96 } 97 return false; 98 } 99 100 void unite(const OverlapMapContainer& otherContainer) 101 { 102 m_layerRects.append(otherContainer.m_layerRects); 103 m_boundingBox.unite(otherContainer.m_boundingBox); 104 } 105 private: 106 Vector<IntRect> m_layerRects; 107 IntRect m_boundingBox; 108 }; 109 110 class RenderLayerCompositor::OverlapMap { 111 WTF_MAKE_NONCOPYABLE(OverlapMap); 112 public: 113 OverlapMap() 114 : m_geometryMap(UseTransforms) 115 { 116 // Begin by assuming the root layer will be composited so that there 117 // is something on the stack. The root layer should also never get a 118 // finishCurrentOverlapTestingContext() call. 119 beginNewOverlapTestingContext(); 120 } 121 122 void add(const RenderLayer* layer, const IntRect& bounds) 123 { 124 // Layers do not contribute to overlap immediately--instead, they will 125 // contribute to overlap as soon as they have been recursively processed 126 // and popped off the stack. 127 ASSERT(m_overlapStack.size() >= 2); 128 m_overlapStack[m_overlapStack.size() - 2].add(bounds); 129 m_layers.add(layer); 130 } 131 132 bool contains(const RenderLayer* layer) 133 { 134 return m_layers.contains(layer); 135 } 136 137 bool overlapsLayers(const IntRect& bounds) const 138 { 139 return m_overlapStack.last().overlapsLayers(bounds); 140 } 141 142 bool isEmpty() 143 { 144 return m_layers.isEmpty(); 145 } 146 147 void beginNewOverlapTestingContext() 148 { 149 // This effectively creates a new "clean slate" for overlap state. 150 // This is used when we know that a subtree or remaining set of 151 // siblings does not need to check overlap with things behind it. 152 m_overlapStack.append(OverlapMapContainer()); 153 } 154 155 void finishCurrentOverlapTestingContext() 156 { 157 // The overlap information on the top of the stack is still necessary 158 // for checking overlap of any layers outside this context that may 159 // overlap things from inside this context. Therefore, we must merge 160 // the information from the top of the stack before popping the stack. 161 // 162 // FIXME: we may be able to avoid this deep copy by rearranging how 163 // overlapMap state is managed. 164 m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last()); 165 m_overlapStack.removeLast(); 166 } 167 168 RenderGeometryMap& geometryMap() { return m_geometryMap; } 169 170 private: 171 Vector<OverlapMapContainer> m_overlapStack; 172 HashSet<const RenderLayer*> m_layers; 173 RenderGeometryMap m_geometryMap; 174 }; 175 176 struct CompositingRecursionData { 177 CompositingRecursionData(RenderLayer* compAncestor, bool testOverlap) 178 : m_compositingAncestor(compAncestor) 179 , m_subtreeIsCompositing(false) 180 , m_hasUnisolatedCompositedBlendingDescendant(false) 181 , m_testingOverlap(testOverlap) 182 #ifndef NDEBUG 183 , m_depth(0) 184 #endif 185 { 186 } 187 188 CompositingRecursionData(const CompositingRecursionData& other) 189 : m_compositingAncestor(other.m_compositingAncestor) 190 , m_subtreeIsCompositing(other.m_subtreeIsCompositing) 191 , m_hasUnisolatedCompositedBlendingDescendant(other.m_hasUnisolatedCompositedBlendingDescendant) 192 , m_testingOverlap(other.m_testingOverlap) 193 #ifndef NDEBUG 194 , m_depth(other.m_depth + 1) 195 #endif 196 { 197 } 198 199 RenderLayer* m_compositingAncestor; 200 bool m_subtreeIsCompositing; 201 bool m_hasUnisolatedCompositedBlendingDescendant; 202 bool m_testingOverlap; 203 #ifndef NDEBUG 204 int m_depth; 205 #endif 206 }; 207 208 209 RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView) 210 : m_renderView(renderView) 211 , m_hasAcceleratedCompositing(true) 212 , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers)) 213 , m_showRepaintCounter(false) 214 , m_needsToRecomputeCompositingRequirements(false) 215 , m_needsToUpdateLayerTreeGeometry(false) 216 , m_compositing(false) 217 , m_compositingLayersNeedRebuild(false) 218 , m_forceCompositingMode(false) 219 , m_inPostLayoutUpdate(false) 220 , m_needsUpdateCompositingRequirementsState(false) 221 , m_isTrackingRepaints(false) 222 , m_rootLayerAttachment(RootLayerUnattached) 223 { 224 } 225 226 RenderLayerCompositor::~RenderLayerCompositor() 227 { 228 ASSERT(m_rootLayerAttachment == RootLayerUnattached); 229 } 230 231 void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */) 232 { 233 if (enable != m_compositing) { 234 m_compositing = enable; 235 236 if (m_compositing) { 237 ensureRootLayer(); 238 notifyIFramesOfCompositingChange(); 239 } else 240 destroyRootLayer(); 241 } 242 } 243 244 void RenderLayerCompositor::cacheAcceleratedCompositingFlags() 245 { 246 bool hasAcceleratedCompositing = false; 247 bool showRepaintCounter = false; 248 bool forceCompositingMode = false; 249 250 if (Settings* settings = m_renderView->document().settings()) { 251 hasAcceleratedCompositing = settings->acceleratedCompositingEnabled(); 252 253 // We allow the chrome to override the settings, in case the page is rendered 254 // on a chrome that doesn't allow accelerated compositing. 255 if (hasAcceleratedCompositing) { 256 if (Page* page = this->page()) { 257 m_compositingTriggers = page->chrome().client().allowedCompositingTriggers(); 258 hasAcceleratedCompositing = m_compositingTriggers; 259 } 260 } 261 262 showRepaintCounter = settings->showRepaintCounter(); 263 forceCompositingMode = settings->forceCompositingMode() && hasAcceleratedCompositing; 264 265 if (forceCompositingMode && !isMainFrame()) 266 forceCompositingMode = requiresCompositingForScrollableFrame(); 267 } 268 269 if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode) 270 setCompositingLayersNeedRebuild(); 271 272 m_hasAcceleratedCompositing = hasAcceleratedCompositing; 273 m_showRepaintCounter = showRepaintCounter; 274 m_forceCompositingMode = forceCompositingMode; 275 } 276 277 bool RenderLayerCompositor::layerSquashingEnabled() const 278 { 279 if (Settings* settings = m_renderView->document().settings()) 280 return settings->layerSquashingEnabled(); 281 282 return false; 283 } 284 285 bool RenderLayerCompositor::canRender3DTransforms() const 286 { 287 return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger); 288 } 289 290 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild) 291 { 292 // FIXME: crbug,com/332248 ideally this could be merged with setNeedsCompositingUpdate(). 293 if (inCompositingMode()) 294 m_compositingLayersNeedRebuild = needRebuild; 295 296 m_renderView->frameView()->scheduleAnimation(); 297 } 298 299 void RenderLayerCompositor::didChangeVisibleRect() 300 { 301 GraphicsLayer* rootLayer = rootGraphicsLayer(); 302 if (!rootLayer) 303 return; 304 305 FrameView* frameView = m_renderView ? m_renderView->frameView() : 0; 306 if (!frameView) 307 return; 308 309 IntRect visibleRect = m_containerLayer ? IntRect(IntPoint(), frameView->contentsSize()) : frameView->visibleContentRect(); 310 if (rootLayer->visibleRectChangeRequiresFlush(visibleRect)) { 311 if (Page* page = this->page()) 312 page->chrome().client().scheduleCompositingLayerFlush(); 313 } 314 } 315 316 void RenderLayerCompositor::updateCompositingRequirementsState() 317 { 318 if (!m_needsUpdateCompositingRequirementsState) 319 return; 320 321 TRACE_EVENT0("blink_rendering,comp-scroll", "RenderLayerCompositor::updateCompositingRequirementsState"); 322 323 m_needsUpdateCompositingRequirementsState = false; 324 325 if (!rootRenderLayer() || !rootRenderLayer()->acceleratedCompositingForOverflowScrollEnabled()) 326 return; 327 328 for (HashSet<RenderLayer*>::iterator it = m_outOfFlowPositionedLayers.begin(); it != m_outOfFlowPositionedLayers.end(); ++it) 329 (*it)->updateHasUnclippedDescendant(); 330 331 const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView->frameView()->scrollableAreas(); 332 if (!scrollableAreas) 333 return; 334 335 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it) 336 (*it)->updateNeedsCompositedScrolling(); 337 } 338 339 static RenderVideo* findFullscreenVideoRenderer(Document* document) 340 { 341 Element* fullscreenElement = FullscreenElementStack::currentFullScreenElementFrom(document); 342 while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) { 343 document = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument(); 344 if (!document) 345 return 0; 346 fullscreenElement = FullscreenElementStack::currentFullScreenElementFrom(document); 347 } 348 if (!fullscreenElement || !isHTMLVideoElement(fullscreenElement)) 349 return 0; 350 RenderObject* renderer = fullscreenElement->renderer(); 351 if (!renderer) 352 return 0; 353 return toRenderVideo(renderer); 354 } 355 356 void RenderLayerCompositor::finishCompositingUpdateForFrameTree(Frame* frame) 357 { 358 for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) 359 finishCompositingUpdateForFrameTree(child); 360 361 // Update compositing for current frame after all descendant frames are updated. 362 if (frame && frame->contentRenderer()) { 363 RenderLayerCompositor* frameCompositor = frame->contentRenderer()->compositor(); 364 if (frameCompositor && !frameCompositor->isMainFrame()) 365 frame->contentRenderer()->compositor()->updateCompositingLayers(CompositingUpdateFinishAllDeferredWork); 366 } 367 } 368 369 void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType) 370 { 371 // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished. 372 if (m_renderView->needsLayout()) 373 return; 374 375 if (updateType == CompositingUpdateFinishAllDeferredWork && isMainFrame() && m_renderView->frameView()) 376 finishCompositingUpdateForFrameTree(&m_renderView->frameView()->frame()); 377 378 if (m_forceCompositingMode && !m_compositing) 379 enableCompositingMode(true); 380 381 if (!m_needsToRecomputeCompositingRequirements && !m_compositing) 382 return; 383 384 AnimationUpdateBlock animationUpdateBlock(m_renderView->frameView()->frame().animation()); 385 386 TemporaryChange<bool> postLayoutChange(m_inPostLayoutUpdate, true); 387 388 bool needCompositingRequirementsUpdate = false; 389 bool needHierarchyAndGeometryUpdate = false; 390 bool needGeometryUpdate = false; 391 bool needsToUpdateScrollingCoordinator = false; 392 393 // CompositingUpdateFinishAllDeferredWork is the only updateType that will actually do any work in this 394 // function. All other updateTypes will simply mark that something needed updating, and defer the actual 395 // update. This way we only need to compute all compositing state once for every frame drawn (if needed). 396 switch (updateType) { 397 case CompositingUpdateAfterStyleChange: 398 case CompositingUpdateAfterLayout: 399 m_needsToRecomputeCompositingRequirements = true; 400 break; 401 case CompositingUpdateOnScroll: 402 m_needsToRecomputeCompositingRequirements = true; // Overlap can change with scrolling, so need to check for hierarchy updates. 403 m_needsToUpdateLayerTreeGeometry = true; 404 break; 405 case CompositingUpdateOnCompositedScroll: 406 m_needsToUpdateLayerTreeGeometry = true; 407 break; 408 case CompositingUpdateFinishAllDeferredWork: 409 needCompositingRequirementsUpdate = m_needsToRecomputeCompositingRequirements; 410 needHierarchyAndGeometryUpdate = m_compositingLayersNeedRebuild; 411 needGeometryUpdate = m_needsToUpdateLayerTreeGeometry; 412 needsToUpdateScrollingCoordinator = scrollingCoordinator() ? scrollingCoordinator()->needsToUpdateAfterCompositingChange() : false; 413 break; 414 } 415 416 if (!needCompositingRequirementsUpdate && !needHierarchyAndGeometryUpdate && !needGeometryUpdate && !needsToUpdateScrollingCoordinator) 417 return; 418 419 ASSERT(updateType == CompositingUpdateFinishAllDeferredWork); 420 421 // Only clear the flags if we're updating the entire hierarchy. 422 m_compositingLayersNeedRebuild = false; 423 m_needsToUpdateLayerTreeGeometry = false; 424 m_needsToRecomputeCompositingRequirements = false; 425 RenderLayer* updateRoot = rootRenderLayer(); 426 427 if (needCompositingRequirementsUpdate) { 428 // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers. 429 // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex. 430 CompositingRecursionData recursionData(updateRoot, true); 431 bool layersChanged = false; 432 bool saw3DTransform = false; 433 { 434 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::computeCompositingRequirements"); 435 OverlapMap overlapTestRequestMap; 436 437 // FIXME: Passing these unclippedDescendants down and keeping track 438 // of them dynamically, we are requiring a full tree walk. This 439 // should be removed as soon as proper overlap testing based on 440 // scrolling and animation bounds is implemented (crbug.com/252472). 441 Vector<RenderLayer*> unclippedDescendants; 442 computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, recursionData, saw3DTransform, unclippedDescendants); 443 } 444 445 { 446 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::assignLayersToBackings"); 447 assignLayersToBackings(updateRoot, layersChanged); 448 } 449 450 { 451 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateHasVisibleNonLayerContentLoop"); 452 const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView->frameView()->scrollableAreas(); 453 if (scrollableAreas) { 454 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it) 455 (*it)->updateHasVisibleNonLayerContent(); 456 } 457 } 458 459 needHierarchyAndGeometryUpdate |= layersChanged; 460 } 461 462 if (needHierarchyAndGeometryUpdate) { 463 // Update the hierarchy of the compositing layers. 464 Vector<GraphicsLayer*> childList; 465 { 466 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::rebuildCompositingLayerTree"); 467 rebuildCompositingLayerTree(updateRoot, childList, 0); 468 } 469 470 // Host the document layer in the RenderView's root layer. 471 if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isMainFrame()) { 472 RenderVideo* video = findFullscreenVideoRenderer(&m_renderView->document()); 473 if (video && video->hasCompositedLayerMapping()) { 474 childList.clear(); 475 childList.append(video->compositedLayerMapping()->mainGraphicsLayer()); 476 } 477 } 478 479 if (childList.isEmpty()) 480 destroyRootLayer(); 481 else 482 m_rootContentLayer->setChildren(childList); 483 } else if (needGeometryUpdate) { 484 // We just need to do a geometry update. This is only used for position:fixed scrolling; 485 // most of the time, geometry is updated via RenderLayer::styleChanged(). 486 updateLayerTreeGeometry(updateRoot); 487 } 488 489 ASSERT(updateRoot || !m_compositingLayersNeedRebuild); 490 491 if (!hasAcceleratedCompositing()) 492 enableCompositingMode(false); 493 494 // The scrolling coordinator may realize that it needs updating while compositing was being updated in this function. 495 needsToUpdateScrollingCoordinator |= scrollingCoordinator() ? scrollingCoordinator()->needsToUpdateAfterCompositingChange() : false; 496 if (needsToUpdateScrollingCoordinator && isMainFrame() && scrollingCoordinator() && inCompositingMode()) 497 scrollingCoordinator()->updateAfterCompositingChange(); 498 499 // Inform the inspector that the layer tree has changed. 500 if (isMainFrame()) 501 InspectorInstrumentation::layerTreeDidChange(page()); 502 } 503 504 static bool requiresCompositing(CompositingReasons reasons) 505 { 506 // Any reasons other than overlap or assumed overlap will require the layer to be separately compositing. 507 return reasons & ~CompositingReasonComboAllOverlapReasons; 508 } 509 510 static bool requiresSquashing(CompositingReasons reasons) 511 { 512 // If the layer has overlap or assumed overlap, but no other reasons, then it should be squashed. 513 return !requiresCompositing(reasons) && (reasons & CompositingReasonComboAllOverlapReasons); 514 } 515 516 static bool requiresCompositingOrSquashing(CompositingReasons reasons) 517 { 518 #ifndef NDEBUG 519 bool fastAnswer = reasons != CompositingReasonNone; 520 bool slowAnswer = requiresCompositing(reasons) || requiresSquashing(reasons); 521 ASSERT(fastAnswer == slowAnswer); 522 #endif 523 return reasons != CompositingReasonNone; 524 } 525 526 void RenderLayerCompositor::addOutOfFlowPositionedLayer(RenderLayer* layer) 527 { 528 m_outOfFlowPositionedLayers.add(layer); 529 } 530 531 void RenderLayerCompositor::removeOutOfFlowPositionedLayer(RenderLayer* layer) 532 { 533 m_outOfFlowPositionedLayers.remove(layer); 534 } 535 536 bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer) 537 { 538 bool compositedLayerMappingChanged = false; 539 RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason; 540 requiresCompositingForPosition(layer->renderer(), layer, &viewportConstrainedNotCompositedReason); 541 542 // FIXME: It would be nice to directly use the layer's compositing reason, 543 // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing 544 // requirements fully. 545 if (needsOwnBacking(layer)) { 546 enableCompositingMode(); 547 548 if (!layer->hasCompositedLayerMapping()) { 549 // If we need to repaint, do so before allocating the compositedLayerMapping 550 repaintOnCompositingChange(layer); 551 552 layer->ensureCompositedLayerMapping(); 553 compositedLayerMappingChanged = true; 554 555 // At this time, the ScrollingCooridnator only supports the top-level frame. 556 if (layer->isRootLayer() && isMainFrame()) { 557 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 558 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView()); 559 } 560 561 // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so 562 // that computing repaint rects will know the layer's correct compositingState. 563 // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping? 564 // Need to create a test where a squashed layer pops into compositing. And also to cover all other 565 // sorts of compositingState transitions. 566 layer->setGroupedMapping(0); 567 568 // FIXME: it seems premature to compute this before all compositing state has been updated? 569 // This layer and all of its descendants have cached repaints rects that are relative to 570 // the repaint container, so change when compositing changes; we need to update them here. 571 if (layer->parent()) 572 layer->repainter().computeRepaintRectsIncludingDescendants(); 573 } 574 575 if (layer->compositedLayerMapping()->updateRequiresOwnBackingStoreForIntrinsicReasons()) 576 compositedLayerMappingChanged = true; 577 } else { 578 if (layer->hasCompositedLayerMapping()) { 579 // If we're removing the compositedLayerMapping from a reflection, clear the source GraphicsLayer's pointer to 580 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection 581 // are both either composited, or not composited. 582 if (layer->isReflection()) { 583 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer(); 584 if (sourceLayer->hasCompositedLayerMapping()) { 585 ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer()); 586 sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->setReplicatedByLayer(0); 587 } 588 } 589 590 removeViewportConstrainedLayer(layer); 591 592 layer->clearCompositedLayerMapping(); 593 compositedLayerMappingChanged = true; 594 595 // This layer and all of its descendants have cached repaints rects that are relative to 596 // the repaint container, so change when compositing changes; we need to update them here. 597 layer->repainter().computeRepaintRectsIncludingDescendants(); 598 599 // If we need to repaint, do so now that we've removed the compositedLayerMapping 600 repaintOnCompositingChange(layer); 601 } 602 } 603 604 if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) { 605 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer())); 606 if (innerCompositor && innerCompositor->inCompositingMode()) 607 innerCompositor->updateRootLayerAttachment(); 608 } 609 610 if (compositedLayerMappingChanged) 611 layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects); 612 613 // If a fixed position layer gained/lost a compositedLayerMapping or the reason not compositing it changed, 614 // the scrolling coordinator needs to recalculate whether it can do fast scrolling. 615 bool nonCompositedReasonChanged = false; 616 if (layer->renderer()->style()->position() == FixedPosition) { 617 if (layer->viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) { 618 layer->setViewportConstrainedNotCompositedReason(viewportConstrainedNotCompositedReason); 619 nonCompositedReasonChanged = true; 620 } 621 if (compositedLayerMappingChanged || nonCompositedReasonChanged) { 622 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 623 scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView->frameView()); 624 } 625 } 626 627 return compositedLayerMappingChanged || nonCompositedReasonChanged; 628 } 629 630 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer) 631 { 632 updateDirectCompositingReasons(layer); 633 bool layerChanged = allocateOrClearCompositedLayerMapping(layer); 634 635 if (layerSquashingEnabled()) { 636 // FIXME: this is not correct... info may be out of date and squashing returning true doesn't indicate that the layer changed 637 layerChanged = requiresSquashing(layer->compositingReasons()); 638 } 639 640 // See if we need content or clipping layers. Methods called here should assume 641 // that the compositing state of descendant layers has not been updated yet. 642 if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateGraphicsLayerConfiguration()) 643 layerChanged = true; 644 645 return layerChanged; 646 } 647 648 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer) 649 { 650 // If the renderer is not attached yet, no need to repaint. 651 if (layer->renderer() != m_renderView && !layer->renderer()->parent()) 652 return; 653 654 RenderLayerModelObject* repaintContainer = layer->renderer()->containerForRepaint(); 655 if (!repaintContainer) 656 repaintContainer = m_renderView; 657 658 layer->repainter().repaintIncludingNonCompositingDescendants(repaintContainer); 659 } 660 661 // This method assumes that layout is up-to-date, unlike repaintOnCompositingChange(). 662 void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, const LayoutRect& rect) 663 { 664 RenderLayer* compositedAncestor = layer->enclosingCompositingLayerForRepaint(false /*exclude self*/); 665 if (compositedAncestor) { 666 // FIXME: make sure repaintRect is computed correctly for squashed scenario 667 LayoutPoint offset; 668 layer->convertToLayerCoords(compositedAncestor, offset); 669 670 LayoutRect repaintRect = rect; 671 repaintRect.moveBy(offset); 672 673 if (compositedAncestor->compositingState() == PaintsIntoOwnBacking) { 674 compositedAncestor->repainter().setBackingNeedsRepaintInRect(repaintRect); 675 } else if (compositedAncestor->compositingState() == PaintsIntoGroupedBacking) { 676 // FIXME: Need to perform the correct coordinate conversion for repaintRect here, including transforms 677 compositedAncestor->groupedMapping()->squashingLayer()->setNeedsDisplayInRect(repaintRect); 678 } else { 679 ASSERT_NOT_REACHED(); 680 } 681 } 682 } 683 684 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant 685 // RenderLayers that are rendered by the composited RenderLayer. 686 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) const 687 { 688 if (!canBeComposited(layer)) 689 return IntRect(); 690 691 RenderLayer::CalculateLayerBoundsFlags flags = RenderLayer::DefaultCalculateLayerBoundsFlags | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask; 692 #if HAVE(COMPOSITOR_FILTER_OUTSETS) 693 // If the compositor computes its own filter outsets, don't include them in the composited bounds. 694 if (!layer->paintsWithFilters()) 695 flags &= ~RenderLayer::IncludeLayerFilterOutsets; 696 #endif 697 return layer->calculateLayerBounds(ancestorLayer, 0, flags); 698 } 699 700 void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/) 701 { 702 setCompositingLayersNeedRebuild(); 703 } 704 705 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child) 706 { 707 if (!child->hasCompositedLayerMapping() || parent->renderer()->documentBeingDestroyed()) 708 return; 709 710 removeViewportConstrainedLayer(child); 711 repaintInCompositedAncestor(child, child->compositedLayerMapping()->compositedBounds()); 712 713 setCompositingParent(child, 0); 714 setCompositingLayersNeedRebuild(); 715 } 716 717 RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const 718 { 719 for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) { 720 if (curr->stackingNode()->isStackingContainer()) 721 return 0; 722 723 if (curr->renderer()->hasClipOrOverflowClip()) 724 return curr; 725 } 726 return 0; 727 } 728 729 void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed) 730 { 731 if (layer->isRootLayer()) 732 return; 733 734 if (!boundsComputed) { 735 // FIXME: If this layer's overlap bounds include its children, we don't need to add its 736 // children's bounds to the overlap map. 737 layerBounds = enclosingIntRect(overlapMap.geometryMap().absoluteRect(layer->overlapBounds())); 738 // Empty rects never intersect, but we need them to for the purposes of overlap testing. 739 if (layerBounds.isEmpty()) 740 layerBounds.setSize(IntSize(1, 1)); 741 boundsComputed = true; 742 } 743 744 IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(ClipRectsContext(rootRenderLayer(), 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions. 745 clipRect.intersect(layerBounds); 746 overlapMap.add(layer, clipRect); 747 } 748 749 void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, RenderLayer* layer, RenderLayer* ancestorLayer) 750 { 751 if (!canBeComposited(layer) || overlapMap.contains(layer)) 752 return; 753 754 // A null ancestorLayer is an indication that 'layer' has already been pushed. 755 if (ancestorLayer) 756 overlapMap.geometryMap().pushMappingsToAncestor(layer, ancestorLayer); 757 758 IntRect bounds; 759 bool haveComputedBounds = false; 760 addToOverlapMap(overlapMap, layer, bounds, haveComputedBounds); 761 762 #if !ASSERT_DISABLED 763 LayerListMutationDetector mutationChecker(layer->stackingNode()); 764 #endif 765 766 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren); 767 while (RenderLayerStackingNode* curNode = iterator.next()) 768 addToOverlapMapRecursive(overlapMap, curNode->layer(), layer); 769 770 if (ancestorLayer) 771 overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer); 772 } 773 774 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order) 775 // For the z-order children of a compositing layer: 776 // If a child layers has a compositing layer, then all subsequent layers must 777 // be compositing in order to render above that layer. 778 // 779 // If a child in the negative z-order list is compositing, then the layer itself 780 // must be compositing so that its contents render over that child. 781 // This implies that its positive z-index children must also be compositing. 782 // 783 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap* overlapMap, CompositingRecursionData& currentRecursionData, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants) 784 { 785 layer->stackingNode()->updateLayerListsIfNeeded(); 786 787 if (overlapMap) 788 overlapMap->geometryMap().pushMappingsToAncestor(layer, ancestorLayer); 789 790 // Clear the flag 791 layer->setHasCompositingDescendant(false); 792 layer->setHasNonCompositedChild(false); 793 794 // Start by assuming this layer will not need to composite. 795 CompositingReasons reasonsToComposite = CompositingReasonNone; 796 797 // First accumulate the straightforward compositing reasons. 798 CompositingReasons directReasons = directReasonsForCompositing(layer); 799 800 // Video is special. It's the only RenderLayer type that can both have 801 // RenderLayer children and whose children can't use its backing to render 802 // into. These children (the controls) always need to be promoted into their 803 // own layers to draw on top of the accelerated video. 804 if (currentRecursionData.m_compositingAncestor && currentRecursionData.m_compositingAncestor->renderer()->isVideo()) 805 directReasons |= CompositingReasonLayerForVideoOverlay; 806 807 if (canBeComposited(layer)) 808 reasonsToComposite |= directReasons; 809 810 // Next, accumulate reasons related to overlap. 811 // If overlap testing is used, this reason will be overridden. If overlap testing is not 812 // used, we must assume we overlap if there is anything composited behind us in paint-order. 813 CompositingReasons overlapCompositingReason = currentRecursionData.m_subtreeIsCompositing ? CompositingReasonAssumedOverlap : CompositingReasonNone; 814 815 if (rootRenderLayer()->compositorDrivenAcceleratedScrollingEnabled()) { 816 Vector<size_t> unclippedDescendantsToRemove; 817 for (size_t i = 0; i < unclippedDescendants.size(); i++) { 818 RenderLayer* unclippedDescendant = unclippedDescendants.at(i); 819 // If we've reached the containing block of one of the unclipped 820 // descendants, that element is no longer relevant to whether or not we 821 // should opt in. Unfortunately we can't easily remove from the list 822 // while we're iterating, so we have to store it for later removal. 823 if (unclippedDescendant->renderer()->containingBlock() == layer->renderer()) { 824 unclippedDescendantsToRemove.append(i); 825 continue; 826 } 827 if (layer->scrollsWithRespectTo(unclippedDescendant)) 828 reasonsToComposite |= CompositingReasonAssumedOverlap; 829 } 830 831 // Remove irrelevant unclipped descendants in reverse order so our stored 832 // indices remain valid. 833 for (size_t i = 0; i < unclippedDescendantsToRemove.size(); i++) 834 unclippedDescendants.remove(unclippedDescendantsToRemove.at(unclippedDescendantsToRemove.size() - i - 1)); 835 836 if (reasonsToComposite & CompositingReasonOutOfFlowClipping) 837 unclippedDescendants.append(layer); 838 } 839 840 bool haveComputedBounds = false; 841 IntRect absBounds; 842 // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map. 843 if (overlapMap && !overlapMap->isEmpty() && currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons)) { 844 // If we're testing for overlap, we only need to composite if we overlap something that is already composited. 845 absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer->overlapBounds())); 846 847 // Empty rects never intersect, but we need them to for the purposes of overlap testing. 848 if (absBounds.isEmpty()) 849 absBounds.setSize(IntSize(1, 1)); 850 haveComputedBounds = true; 851 overlapCompositingReason = overlapMap->overlapsLayers(absBounds) ? CompositingReasonOverlap : CompositingReasonNone; 852 } 853 854 reasonsToComposite |= overlapCompositingReason; 855 856 // The children of this layer don't need to composite, unless there is 857 // a compositing layer among them, so start by inheriting the compositing 858 // ancestor with m_subtreeIsCompositing set to false. 859 CompositingRecursionData childRecursionData(currentRecursionData); 860 childRecursionData.m_subtreeIsCompositing = false; 861 862 bool willBeComposited = canBeComposited(layer) && requiresCompositingOrSquashing(reasonsToComposite); 863 if (willBeComposited) { 864 // Tell the parent it has compositing descendants. 865 currentRecursionData.m_subtreeIsCompositing = true; 866 // This layer now acts as the ancestor for kids. 867 childRecursionData.m_compositingAncestor = layer; 868 869 // Here we know that all children and the layer's own contents can blindly paint into 870 // this layer's backing, until a descendant is composited. So, we don't need to check 871 // for overlap with anything behind this layer. 872 if (overlapMap) 873 overlapMap->beginNewOverlapTestingContext(); 874 // This layer is going to be composited, so children can safely ignore the fact that there's an 875 // animation running behind this layer, meaning they can rely on the overlap map testing again. 876 childRecursionData.m_testingOverlap = true; 877 } 878 879 #if !ASSERT_DISABLED 880 LayerListMutationDetector mutationChecker(layer->stackingNode()); 881 #endif 882 883 bool anyDescendantHas3DTransform = false; 884 bool willHaveForegroundLayer = false; 885 886 if (layer->stackingNode()->isStackingContainer()) { 887 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren); 888 while (RenderLayerStackingNode* curNode = iterator.next()) { 889 computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants); 890 891 // If we have to make a layer for this child, make one now so we can have a contents layer 892 // (since we need to ensure that the -ve z-order child renders underneath our contents). 893 if (childRecursionData.m_subtreeIsCompositing) { 894 reasonsToComposite |= CompositingReasonNegativeZIndexChildren; 895 896 if (!willBeComposited) { 897 // make layer compositing 898 childRecursionData.m_compositingAncestor = layer; 899 overlapMap->beginNewOverlapTestingContext(); 900 willBeComposited = true; 901 willHaveForegroundLayer = true; 902 903 // FIXME: temporary solution for the first negative z-index composited child: 904 // re-compute the absBounds for the child so that we can add the 905 // negative z-index child's bounds to the new overlap context. 906 if (overlapMap) { 907 overlapMap->geometryMap().pushMappingsToAncestor(curNode->layer(), layer); 908 IntRect childAbsBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(curNode->layer()->overlapBounds())); 909 bool boundsComputed = true; 910 overlapMap->beginNewOverlapTestingContext(); 911 addToOverlapMap(*overlapMap, curNode->layer(), childAbsBounds, boundsComputed); 912 overlapMap->finishCurrentOverlapTestingContext(); 913 overlapMap->geometryMap().popMappingsToAncestor(layer); 914 } 915 } 916 } 917 } 918 } 919 920 if (overlapMap && willHaveForegroundLayer) { 921 ASSERT(willBeComposited); 922 // A foreground layer effectively is a new backing for all subsequent children, so 923 // we don't need to test for overlap with anything behind this. So, we can finish 924 // the previous context that was accumulating rects for the negative z-index 925 // children, and start with a fresh new empty context. 926 overlapMap->finishCurrentOverlapTestingContext(); 927 overlapMap->beginNewOverlapTestingContext(); 928 // This layer is going to be composited, so children can safely ignore the fact that there's an 929 // animation running behind this layer, meaning they can rely on the overlap map testing again 930 childRecursionData.m_testingOverlap = true; 931 } 932 933 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren); 934 while (RenderLayerStackingNode* curNode = iterator.next()) 935 computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants); 936 937 // Now that the subtree has been traversed, we can check for compositing reasons that depended on the state of the subtree. 938 939 // If we entered compositing mode during the recursion, the root will also need to be composited (as long as accelerated compositing is enabled). 940 if (layer->isRootLayer()) { 941 if (inCompositingMode() && m_hasAcceleratedCompositing) 942 willBeComposited = true; 943 } 944 945 // All layers (even ones that aren't being composited) need to get added to 946 // the overlap map. Layers that are not separately composited will paint into their 947 // compositing ancestor's backing, and so are still considered for overlap. 948 if (overlapMap && childRecursionData.m_compositingAncestor && !childRecursionData.m_compositingAncestor->isRootLayer()) 949 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 950 951 if (layer->stackingNode()->isStackingContext()) { 952 layer->setShouldIsolateCompositedDescendants(childRecursionData.m_hasUnisolatedCompositedBlendingDescendant); 953 } else { 954 layer->setShouldIsolateCompositedDescendants(false); 955 currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = childRecursionData.m_hasUnisolatedCompositedBlendingDescendant; 956 } 957 958 // Now check for reasons to become composited that depend on the state of descendant layers. 959 CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing(layer->renderer(), childRecursionData.m_subtreeIsCompositing, anyDescendantHas3DTransform); 960 reasonsToComposite |= subtreeCompositingReasons; 961 if (!willBeComposited && canBeComposited(layer) && requiresCompositingOrSquashing(subtreeCompositingReasons)) { 962 childRecursionData.m_compositingAncestor = layer; 963 if (overlapMap) { 964 // FIXME: this context push is effectively a no-op but needs to exist for 965 // now, because the code is designed to push overlap information to the 966 // second-from-top context of the stack. 967 overlapMap->beginNewOverlapTestingContext(); 968 addToOverlapMapRecursive(*overlapMap, layer); 969 } 970 willBeComposited = true; 971 } 972 973 // If the original layer is composited, the reflection needs to be, too. 974 if (layer->reflectionInfo()) { 975 // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer? 976 CompositingReasons reflectionCompositingReason = willBeComposited ? CompositingReasonReflectionOfCompositedParent : CompositingReasonNone; 977 layer->reflectionInfo()->reflectionLayer()->setCompositingReasons(layer->reflectionInfo()->reflectionLayer()->compositingReasons() | reflectionCompositingReason); 978 } 979 980 // Subsequent layers in the parent's stacking context may also need to composite. 981 if (childRecursionData.m_subtreeIsCompositing) 982 currentRecursionData.m_subtreeIsCompositing = true; 983 984 if (willBeComposited && layer->hasBlendMode()) 985 currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = true; 986 987 // Set the flag to say that this SC has compositing children. 988 layer->setHasCompositingDescendant(childRecursionData.m_subtreeIsCompositing); 989 990 // Turn overlap testing off for later layers if it's already off, or if we have an animating transform. 991 // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because 992 // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map. 993 bool isCompositedClippingLayer = canBeComposited(layer) && (reasonsToComposite & CompositingReasonClipsCompositingDescendants); 994 if ((!childRecursionData.m_testingOverlap && !isCompositedClippingLayer) || isRunningAcceleratedTransformAnimation(layer->renderer())) 995 currentRecursionData.m_testingOverlap = false; 996 997 if (overlapMap && childRecursionData.m_compositingAncestor == layer && !layer->isRootLayer()) 998 overlapMap->finishCurrentOverlapTestingContext(); 999 1000 if (layer->isRootLayer()) { 1001 // The root layer needs to be composited if anything else in the tree is composited. 1002 // Otherwise, we can disable compositing entirely. 1003 if (childRecursionData.m_subtreeIsCompositing || requiresCompositingOrSquashing(reasonsToComposite) || m_forceCompositingMode) { 1004 willBeComposited = true; 1005 reasonsToComposite |= CompositingReasonRoot; 1006 } else { 1007 enableCompositingMode(false); 1008 willBeComposited = false; 1009 reasonsToComposite = CompositingReasonNone; 1010 } 1011 } 1012 1013 // At this point we have finished collecting all reasons to composite this layer. 1014 layer->setCompositingReasons(reasonsToComposite); 1015 1016 if (!willBeComposited && layer->parent()) 1017 layer->parent()->setHasNonCompositedChild(true); 1018 1019 descendantHas3DTransform |= anyDescendantHas3DTransform || layer->has3DTransform(); 1020 1021 if (overlapMap) 1022 overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer); 1023 } 1024 1025 void RenderLayerCompositor::SquashingState::updateSquashingStateForNewMapping(CompositedLayerMappingPtr newCompositedLayerMapping, bool hasNewCompositedLayerMapping, IntPoint newOffsetFromAbsolute) 1026 { 1027 // The most recent backing is done accumulating any more squashing layers. 1028 if (hasMostRecentMapping) 1029 mostRecentMapping->finishAccumulatingSquashingLayers(nextSquashedLayerIndex); 1030 1031 nextSquashedLayerIndex = 0; 1032 mostRecentMapping = newCompositedLayerMapping; 1033 hasMostRecentMapping = hasNewCompositedLayerMapping; 1034 offsetFromAbsolute = newOffsetFromAbsolute; 1035 } 1036 1037 static IntPoint computeOffsetFromAbsolute(RenderLayer* layer) 1038 { 1039 TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint()); 1040 layer->renderer()->mapLocalToContainer(0, transformState, ApplyContainerFlip); 1041 transformState.flatten(); 1042 return roundedIntPoint(transformState.lastPlanarPoint()); 1043 } 1044 1045 void RenderLayerCompositor::assignLayersToBackings(RenderLayer* updateRoot, bool& layersChanged) 1046 { 1047 SquashingState squashingState; 1048 assignLayersToBackingsInternal(updateRoot, squashingState, layersChanged); 1049 if (squashingState.hasMostRecentMapping) 1050 squashingState.mostRecentMapping->finishAccumulatingSquashingLayers(squashingState.nextSquashedLayerIndex); 1051 } 1052 1053 void RenderLayerCompositor::assignLayersToBackingsInternal(RenderLayer* layer, SquashingState& squashingState, bool& layersChanged) 1054 { 1055 if (allocateOrClearCompositedLayerMapping(layer)) 1056 layersChanged = true; 1057 1058 if (layer->reflectionInfo() && updateLayerCompositingState(layer->reflectionInfo()->reflectionLayer())) 1059 layersChanged = true; 1060 1061 // Add this layer to a squashing backing if needed. 1062 if (layerSquashingEnabled()) { 1063 // NOTE: In the future as we generalize this, the background of this layer may need to be assigned to a different backing than 1064 // the layer's own primary contents. This would happen when we have a composited negative z-index element that needs to 1065 // paint on top of the background, but below the layer's main contents. For now, because we always composite layers 1066 // when they have a composited negative z-index child, such layers will never need squashing so it is not yet an issue. 1067 if (requiresSquashing(layer->compositingReasons())) { 1068 // A layer that is squashed with other layers cannot have its own CompositedLayerMapping. 1069 ASSERT(!layer->hasCompositedLayerMapping()); 1070 ASSERT(squashingState.hasMostRecentMapping); 1071 1072 IntPoint offsetFromAbsolute = computeOffsetFromAbsolute(layer); 1073 1074 // FIXME: see if we can refactor this to be clearer 1075 IntSize offsetFromTargetBacking(offsetFromAbsolute.x() - squashingState.offsetFromAbsolute.x(), 1076 offsetFromAbsolute.y() - squashingState.offsetFromAbsolute.y()); 1077 1078 squashingState.mostRecentMapping->addRenderLayerToSquashingGraphicsLayer(layer, offsetFromTargetBacking, squashingState.nextSquashedLayerIndex); 1079 squashingState.nextSquashedLayerIndex++; 1080 1081 // FIXME: does this need to be true here? Do we need more logic to decide when it should be true? 1082 layersChanged = true; 1083 1084 // FIXME: this should be conditioned on whether this layer actually changed status 1085 layer->clipper().clearClipRectsIncludingDescendants(); 1086 } 1087 } 1088 1089 if (layer->stackingNode()->isStackingContainer()) { 1090 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren); 1091 while (RenderLayerStackingNode* curNode = iterator.next()) 1092 assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged); 1093 } 1094 1095 if (layerSquashingEnabled()) { 1096 // At this point, if the layer is to be "separately" composited, then its backing becomes the most recent in paint-order. 1097 if (layer->compositingState() == PaintsIntoOwnBacking || layer->compositingState() == HasOwnBackingButPaintsIntoAncestor) { 1098 ASSERT(!requiresSquashing(layer->compositingReasons())); 1099 IntPoint offsetFromAbsolute = computeOffsetFromAbsolute(layer); 1100 squashingState.updateSquashingStateForNewMapping(layer->compositedLayerMapping(), layer->hasCompositedLayerMapping(), offsetFromAbsolute); 1101 } 1102 } 1103 1104 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren); 1105 while (RenderLayerStackingNode* curNode = iterator.next()) 1106 assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged); 1107 } 1108 1109 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer) 1110 { 1111 ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer); 1112 ASSERT(childLayer->hasCompositedLayerMapping()); 1113 1114 // It's possible to be called with a parent that isn't yet composited when we're doing 1115 // partial updates as required by painting or hit testing. Just bail in that case; 1116 // we'll do a full layer update soon. 1117 if (!parentLayer || !parentLayer->hasCompositedLayerMapping()) 1118 return; 1119 1120 if (parentLayer) { 1121 GraphicsLayer* hostingLayer = parentLayer->compositedLayerMapping()->parentForSublayers(); 1122 GraphicsLayer* hostedLayer = childLayer->compositedLayerMapping()->childForSuperlayers(); 1123 1124 hostingLayer->addChild(hostedLayer); 1125 } else { 1126 childLayer->compositedLayerMapping()->childForSuperlayers()->removeFromParent(); 1127 } 1128 } 1129 1130 void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer) 1131 { 1132 ASSERT(layer->hasCompositedLayerMapping()); 1133 1134 GraphicsLayer* hostingLayer = layer->compositedLayerMapping()->parentForSublayers(); 1135 hostingLayer->removeAllChildren(); 1136 } 1137 1138 bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const 1139 { 1140 if (!m_hasAcceleratedCompositing) 1141 return false; 1142 1143 return o->supportsAcceleratedRendering(); 1144 } 1145 1146 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth) 1147 { 1148 // Make the layer compositing if necessary, and set up clipping and content layers. 1149 // Note that we can only do work here that is independent of whether the descendant layers 1150 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary. 1151 1152 layer->stackingNode()->updateLayerListsIfNeeded(); 1153 1154 // Used for gathering UMA data about the effect on memory usage of promoting all layers 1155 // that have a webkit-transition on opacity or transform and intersect the viewport. 1156 static double pixelsWithoutPromotingAllTransitions = 0.0; 1157 static double pixelsAddedByPromotingAllTransitions = 0.0; 1158 1159 if (!depth) { 1160 pixelsWithoutPromotingAllTransitions = 0.0; 1161 pixelsAddedByPromotingAllTransitions = 0.0; 1162 } 1163 1164 const bool hasCompositedLayerMapping = layer->hasCompositedLayerMapping(); 1165 CompositedLayerMappingPtr currentCompositedLayerMapping = layer->compositedLayerMapping(); 1166 if (hasCompositedLayerMapping) { 1167 // The compositing state of all our children has been updated already, so now 1168 // we can compute and cache the composited bounds for this layer. 1169 currentCompositedLayerMapping->updateCompositedBounds(); 1170 1171 if (layer->reflectionInfo()) { 1172 RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer(); 1173 if (reflectionLayer->hasCompositedLayerMapping()) 1174 reflectionLayer->compositedLayerMapping()->updateCompositedBounds(); 1175 } 1176 1177 currentCompositedLayerMapping->updateGraphicsLayerConfiguration(); 1178 currentCompositedLayerMapping->updateGraphicsLayerGeometry(); 1179 1180 if (!layer->parent()) 1181 updateRootLayerPosition(); 1182 1183 if (currentCompositedLayerMapping->hasUnpositionedOverflowControlsLayers()) 1184 layer->scrollableArea()->positionOverflowControls(); 1185 1186 pixelsWithoutPromotingAllTransitions += layer->size().height() * layer->size().width(); 1187 } else { 1188 if ((layer->renderer()->style()->transitionForProperty(CSSPropertyOpacity) || 1189 layer->renderer()->style()->transitionForProperty(CSSPropertyWebkitTransform)) && 1190 m_renderView->viewRect().intersects(layer->absoluteBoundingBox())) 1191 pixelsAddedByPromotingAllTransitions += layer->size().height() * layer->size().width(); 1192 } 1193 1194 // If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers. 1195 // Otherwise children continue to append to the child list of the enclosing layer. 1196 Vector<GraphicsLayer*> layerChildren; 1197 Vector<GraphicsLayer*>& childList = hasCompositedLayerMapping ? layerChildren : childLayersOfEnclosingLayer; 1198 1199 #if !ASSERT_DISABLED 1200 LayerListMutationDetector mutationChecker(layer->stackingNode()); 1201 #endif 1202 1203 if (layer->stackingNode()->isStackingContainer()) { 1204 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren); 1205 while (RenderLayerStackingNode* curNode = iterator.next()) 1206 rebuildCompositingLayerTree(curNode->layer(), childList, depth + 1); 1207 1208 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented. 1209 if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer()) 1210 childList.append(currentCompositedLayerMapping->foregroundLayer()); 1211 } 1212 1213 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren); 1214 while (RenderLayerStackingNode* curNode = iterator.next()) 1215 rebuildCompositingLayerTree(curNode->layer(), childList, depth + 1); 1216 1217 if (hasCompositedLayerMapping) { 1218 bool parented = false; 1219 if (layer->renderer()->isRenderPart()) 1220 parented = parentFrameContentLayers(toRenderPart(layer->renderer())); 1221 1222 if (!parented) 1223 currentCompositedLayerMapping->parentForSublayers()->setChildren(layerChildren); 1224 1225 // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer. 1226 // Otherwise, the overflow control layers are normal children. 1227 if (!currentCompositedLayerMapping->hasClippingLayer() && !currentCompositedLayerMapping->hasScrollingLayer()) { 1228 if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForHorizontalScrollbar()) { 1229 overflowControlLayer->removeFromParent(); 1230 currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer); 1231 } 1232 1233 if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForVerticalScrollbar()) { 1234 overflowControlLayer->removeFromParent(); 1235 currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer); 1236 } 1237 1238 if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForScrollCorner()) { 1239 overflowControlLayer->removeFromParent(); 1240 currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer); 1241 } 1242 } 1243 1244 childLayersOfEnclosingLayer.append(currentCompositedLayerMapping->childForSuperlayers()); 1245 } 1246 1247 if (!depth) { 1248 int percentageIncreaseInPixels = static_cast<int>(pixelsAddedByPromotingAllTransitions / pixelsWithoutPromotingAllTransitions * 100); 1249 blink::Platform::current()->histogramCustomCounts("Renderer.PixelIncreaseFromTransitions", percentageIncreaseInPixels, 0, 1000, 50); 1250 } 1251 } 1252 1253 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset) 1254 { 1255 if (m_overflowControlsHostLayer) 1256 m_overflowControlsHostLayer->setPosition(contentsOffset); 1257 } 1258 1259 void RenderLayerCompositor::frameViewDidChangeSize() 1260 { 1261 if (m_containerLayer) { 1262 FrameView* frameView = m_renderView->frameView(); 1263 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); 1264 1265 frameViewDidScroll(); 1266 updateOverflowControlsLayers(); 1267 } 1268 } 1269 1270 enum AcceleratedFixedRootBackgroundHistogramBuckets { 1271 ScrolledMainFrameBucket = 0, 1272 ScrolledMainFrameWithAcceleratedFixedRootBackground = 1, 1273 ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2, 1274 AcceleratedFixedRootBackgroundHistogramMax = 3 1275 }; 1276 1277 void RenderLayerCompositor::frameViewDidScroll() 1278 { 1279 FrameView* frameView = m_renderView->frameView(); 1280 IntPoint scrollPosition = frameView->scrollPosition(); 1281 1282 if (!m_scrollLayer) 1283 return; 1284 1285 bool scrollingCoordinatorHandlesOffset = false; 1286 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) { 1287 if (Settings* settings = m_renderView->document().settings()) { 1288 if (isMainFrame() || settings->compositedScrollingForFramesEnabled()) 1289 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView); 1290 } 1291 } 1292 1293 // Scroll position = scroll minimum + scroll offset. Adjust the layer's 1294 // position to handle whatever the scroll coordinator isn't handling. 1295 // The minimum scroll position is non-zero for RTL pages with overflow. 1296 if (scrollingCoordinatorHandlesOffset) 1297 m_scrollLayer->setPosition(-frameView->minimumScrollPosition()); 1298 else 1299 m_scrollLayer->setPosition(-scrollPosition); 1300 1301 1302 blink::Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground", 1303 ScrolledMainFrameBucket, 1304 AcceleratedFixedRootBackgroundHistogramMax); 1305 1306 if (!m_renderView->rootBackgroundIsEntirelyFixed()) 1307 return; 1308 1309 blink::Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground", 1310 !!fixedRootBackgroundLayer() 1311 ? ScrolledMainFrameWithAcceleratedFixedRootBackground 1312 : ScrolledMainFrameWithUnacceleratedFixedRootBackground, 1313 AcceleratedFixedRootBackgroundHistogramMax); 1314 } 1315 1316 void RenderLayerCompositor::frameViewDidLayout() 1317 { 1318 } 1319 1320 void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange() 1321 { 1322 if (m_containerLayer) 1323 updateOverflowControlsLayers(); 1324 } 1325 1326 void RenderLayerCompositor::rootFixedBackgroundsChanged() 1327 { 1328 if (!supportsFixedRootBackgroundCompositing()) 1329 return; 1330 1331 // To avoid having to make the fixed root background layer fixed positioned to 1332 // stay put, we position it in the layer tree as follows: 1333 // 1334 // + Overflow controls host 1335 // + Frame clip 1336 // + (Fixed root background) <-- Here. 1337 // + Frame scroll 1338 // + Root content layer 1339 // + Scrollbars 1340 // 1341 // That is, it needs to be the first child of the frame clip, the sibling of 1342 // the frame scroll layer. The compositor does not own the background layer, it 1343 // just positions it (like the foreground layer). 1344 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer()) 1345 m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get()); 1346 } 1347 1348 bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer) 1349 { 1350 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 1351 return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea()); 1352 return false; 1353 } 1354 1355 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags) 1356 { 1357 // Before dumping the layer tree, finish any pending compositing update. 1358 updateCompositingLayers(CompositingUpdateFinishAllDeferredWork); 1359 1360 if (!m_rootContentLayer) 1361 return String(); 1362 1363 // We skip dumping the scroll and clip layers to keep layerTreeAsText output 1364 // similar between platforms (unless we explicitly request dumping from the 1365 // root. 1366 GraphicsLayer* rootLayer = m_rootContentLayer.get(); 1367 if (flags & LayerTreeIncludesRootLayer) 1368 rootLayer = rootGraphicsLayer(); 1369 1370 String layerTreeText = rootLayer->layerTreeAsText(flags); 1371 1372 // The true root layer is not included in the dump, so if we want to report 1373 // its repaint rects, they must be included here. 1374 if (flags & LayerTreeIncludesRepaintRects) 1375 return m_renderView->frameView()->trackedRepaintRectsAsText() + layerTreeText; 1376 1377 return layerTreeText; 1378 } 1379 1380 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer) 1381 { 1382 if (!renderer->node()->isFrameOwnerElement()) 1383 return 0; 1384 1385 HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node()); 1386 if (Document* contentDocument = element->contentDocument()) { 1387 if (RenderView* view = contentDocument->renderView()) 1388 return view->compositor(); 1389 } 1390 return 0; 1391 } 1392 1393 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer) 1394 { 1395 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer); 1396 if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame) 1397 return false; 1398 1399 RenderLayer* layer = renderer->layer(); 1400 if (!layer->hasCompositedLayerMapping()) 1401 return false; 1402 1403 CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping(); 1404 GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers(); 1405 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer(); 1406 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) { 1407 hostingLayer->removeAllChildren(); 1408 hostingLayer->addChild(rootLayer); 1409 } 1410 return true; 1411 } 1412 1413 // This just updates layer geometry without changing the hierarchy. 1414 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer) 1415 { 1416 if (layer->hasCompositedLayerMapping()) { 1417 CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping(); 1418 // The compositing state of all our children has been updated already, so now 1419 // we can compute and cache the composited bounds for this layer. 1420 compositedLayerMapping->updateCompositedBounds(); 1421 1422 if (layer->reflectionInfo()) { 1423 RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer(); 1424 if (reflectionLayer->hasCompositedLayerMapping()) 1425 reflectionLayer->compositedLayerMapping()->updateCompositedBounds(); 1426 } 1427 1428 compositedLayerMapping->updateGraphicsLayerConfiguration(); 1429 compositedLayerMapping->updateGraphicsLayerGeometry(); 1430 1431 if (!layer->parent()) 1432 updateRootLayerPosition(); 1433 } 1434 1435 #if !ASSERT_DISABLED 1436 LayerListMutationDetector mutationChecker(layer->stackingNode()); 1437 #endif 1438 1439 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren); 1440 while (RenderLayerStackingNode* curNode = iterator.next()) 1441 updateLayerTreeGeometry(curNode->layer()); 1442 } 1443 1444 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry. 1445 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayerStackingNode* compositingAncestor, RenderLayer* layer, bool compositedChildrenOnly) 1446 { 1447 if (layer->stackingNode() != compositingAncestor) { 1448 if (layer->hasCompositedLayerMapping()) { 1449 CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping(); 1450 compositedLayerMapping->updateCompositedBounds(); 1451 1452 if (layer->reflectionInfo()) { 1453 RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer(); 1454 if (reflectionLayer->hasCompositedLayerMapping()) 1455 reflectionLayer->compositedLayerMapping()->updateCompositedBounds(); 1456 } 1457 1458 compositedLayerMapping->updateGraphicsLayerGeometry(); 1459 if (compositedChildrenOnly) 1460 return; 1461 } 1462 } 1463 1464 if (layer->reflectionInfo()) 1465 updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionInfo()->reflectionLayer(), compositedChildrenOnly); 1466 1467 if (!layer->hasCompositingDescendant()) 1468 return; 1469 1470 #if !ASSERT_DISABLED 1471 LayerListMutationDetector mutationChecker(layer->stackingNode()); 1472 #endif 1473 1474 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren); 1475 while (RenderLayerStackingNode* curNode = iterator.next()) 1476 updateCompositingDescendantGeometry(compositingAncestor, curNode->layer(), compositedChildrenOnly); 1477 } 1478 1479 1480 void RenderLayerCompositor::repaintCompositedLayers(const IntRect* absRect) 1481 { 1482 recursiveRepaintLayer(rootRenderLayer(), absRect); 1483 } 1484 1485 void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer* layer, const IntRect* rect) 1486 { 1487 // FIXME: This method does not work correctly with transforms. 1488 if (layer->compositingState() == PaintsIntoOwnBacking) { 1489 if (rect) 1490 layer->repainter().setBackingNeedsRepaintInRect(*rect); 1491 else 1492 layer->repainter().setBackingNeedsRepaint(); 1493 } 1494 1495 #if !ASSERT_DISABLED 1496 LayerListMutationDetector mutationChecker(layer->stackingNode()); 1497 #endif 1498 1499 unsigned childrenToVisit = NormalFlowChildren; 1500 if (layer->hasCompositingDescendant()) 1501 childrenToVisit |= PositiveZOrderChildren | NegativeZOrderChildren; 1502 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), childrenToVisit); 1503 while (RenderLayerStackingNode* curNode = iterator.next()) { 1504 if (rect) { 1505 IntRect childRect(*rect); 1506 curNode->layer()->convertToPixelSnappedLayerCoords(layer, childRect); 1507 recursiveRepaintLayer(curNode->layer(), &childRect); 1508 } else { 1509 recursiveRepaintLayer(curNode->layer()); 1510 } 1511 } 1512 } 1513 1514 RenderLayer* RenderLayerCompositor::rootRenderLayer() const 1515 { 1516 return m_renderView->layer(); 1517 } 1518 1519 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const 1520 { 1521 if (m_overflowControlsHostLayer) 1522 return m_overflowControlsHostLayer.get(); 1523 return m_rootContentLayer.get(); 1524 } 1525 1526 GraphicsLayer* RenderLayerCompositor::scrollLayer() const 1527 { 1528 return m_scrollLayer.get(); 1529 } 1530 1531 void RenderLayerCompositor::setIsInWindow(bool isInWindow) 1532 { 1533 if (!inCompositingMode()) 1534 return; 1535 1536 if (isInWindow) { 1537 if (m_rootLayerAttachment != RootLayerUnattached) 1538 return; 1539 1540 RootLayerAttachment attachment = isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; 1541 attachRootLayer(attachment); 1542 } else { 1543 if (m_rootLayerAttachment == RootLayerUnattached) 1544 return; 1545 1546 detachRootLayer(); 1547 } 1548 } 1549 1550 void RenderLayerCompositor::clearMappingForRenderLayerIncludingDescendants(RenderLayer* layer) 1551 { 1552 if (!layer) 1553 return; 1554 1555 if (layer->hasCompositedLayerMapping()) { 1556 removeViewportConstrainedLayer(layer); 1557 layer->clearCompositedLayerMapping(); 1558 } 1559 1560 for (RenderLayer* currLayer = layer->firstChild(); currLayer; currLayer = currLayer->nextSibling()) 1561 clearMappingForRenderLayerIncludingDescendants(currLayer); 1562 } 1563 1564 void RenderLayerCompositor::clearMappingForAllRenderLayers() 1565 { 1566 clearMappingForRenderLayerIncludingDescendants(m_renderView->layer()); 1567 } 1568 1569 void RenderLayerCompositor::updateRootLayerPosition() 1570 { 1571 if (m_rootContentLayer) { 1572 const IntRect& documentRect = m_renderView->documentRect(); 1573 m_rootContentLayer->setSize(documentRect.size()); 1574 m_rootContentLayer->setPosition(documentRect.location()); 1575 #if USE(RUBBER_BANDING) 1576 if (m_layerForOverhangShadow) 1577 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get()); 1578 #endif 1579 } 1580 if (m_containerLayer) { 1581 FrameView* frameView = m_renderView->frameView(); 1582 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); 1583 } 1584 } 1585 1586 bool RenderLayerCompositor::has3DContent() const 1587 { 1588 return layerHas3DContent(rootRenderLayer()); 1589 } 1590 1591 void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer) 1592 { 1593 CompositingReasons layerReasons = layer->compositingReasons(); 1594 1595 layerReasons &= ~CompositingReasonComboAllDirectReasons; 1596 layerReasons |= directReasonsForCompositing(layer); 1597 layer->setCompositingReasons(layerReasons); 1598 } 1599 1600 bool RenderLayerCompositor::needsOwnBacking(const RenderLayer* layer) const 1601 { 1602 if (!canBeComposited(layer)) 1603 return false; 1604 1605 // If squashing is disabled, then layers that would have been squashed should just be separately composited. 1606 bool needsOwnBackingForDisabledSquashing = !layerSquashingEnabled() && requiresSquashing(layer->compositingReasons()); 1607 1608 return requiresCompositing(layer->compositingReasons()) || needsOwnBackingForDisabledSquashing || (inCompositingMode() && layer->isRootLayer()); 1609 } 1610 1611 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const 1612 { 1613 // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly. 1614 // See http://webkit.org/b/84900 to re-enable it. 1615 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && layer->renderer()->flowThreadState() == RenderObject::NotInsideFlowThread; 1616 } 1617 1618 CompositingReasons RenderLayerCompositor::directReasonsForCompositing(const RenderLayer* layer) const 1619 { 1620 RenderObject* renderer = layer->renderer(); 1621 CompositingReasons directReasons = CompositingReasonNone; 1622 1623 if (requiresCompositingForTransform(renderer)) 1624 directReasons |= CompositingReason3DTransform; 1625 1626 // Only zero or one of the following conditions will be true for a given RenderLayer. 1627 if (requiresCompositingForVideo(renderer)) 1628 directReasons |= CompositingReasonVideo; 1629 else if (requiresCompositingForCanvas(renderer)) 1630 directReasons |= CompositingReasonCanvas; 1631 else if (requiresCompositingForPlugin(renderer)) 1632 directReasons |= CompositingReasonPlugin; 1633 else if (requiresCompositingForFrame(renderer)) 1634 directReasons |= CompositingReasonIFrame; 1635 1636 if (requiresCompositingForBackfaceVisibilityHidden(renderer)) 1637 directReasons |= CompositingReasonBackfaceVisibilityHidden; 1638 1639 if (requiresCompositingForAnimation(renderer)) 1640 directReasons |= CompositingReasonAnimation; 1641 1642 if (requiresCompositingForTransition(renderer)) 1643 directReasons |= CompositingReasonAnimation; 1644 1645 if (requiresCompositingForFilters(renderer)) 1646 directReasons |= CompositingReasonFilters; 1647 1648 if (requiresCompositingForPosition(renderer, layer)) 1649 directReasons |= renderer->style()->position() == FixedPosition ? CompositingReasonPositionFixed : CompositingReasonPositionSticky; 1650 1651 if (requiresCompositingForOverflowScrolling(layer)) 1652 directReasons |= CompositingReasonOverflowScrollingTouch; 1653 1654 if (requiresCompositingForOverflowScrollingParent(layer)) 1655 directReasons |= CompositingReasonOverflowScrollingParent; 1656 1657 if (requiresCompositingForOutOfFlowClipping(layer)) 1658 directReasons |= CompositingReasonOutOfFlowClipping; 1659 1660 return directReasons; 1661 } 1662 1663 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips, 1664 // up to the enclosing compositing ancestor. This is required because compositing layers are parented 1665 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy. 1666 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy, 1667 // but a sibling in the z-order hierarchy. 1668 bool RenderLayerCompositor::clippedByAncestor(const RenderLayer* layer) const 1669 { 1670 if (!layer->hasCompositedLayerMapping() || !layer->parent()) 1671 return false; 1672 1673 // FIXME: need to double-check if semantics of ancestorCompositingLayer() work correctly here? 1674 const RenderLayer* compositingAncestor = layer->ancestorCompositingLayer(); 1675 if (!compositingAncestor) 1676 return false; 1677 1678 // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(), 1679 // so we only care about clipping between its first child that is our ancestor (the computeClipRoot), 1680 // and layer. 1681 const RenderLayer* computeClipRoot = 0; 1682 const RenderLayer* curr = layer; 1683 while (curr) { 1684 const RenderLayer* next = curr->parent(); 1685 if (next == compositingAncestor) { 1686 computeClipRoot = curr; 1687 break; 1688 } 1689 curr = next; 1690 } 1691 1692 if (!computeClipRoot || computeClipRoot == layer) 1693 return false; 1694 1695 return layer->backgroundClipRect(ClipRectsContext(computeClipRoot, 0, TemporaryClipRects)).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions. 1696 } 1697 1698 // Return true if the given layer is a stacking context and has compositing child 1699 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer 1700 // into the hierarchy between this layer and its children in the z-order hierarchy. 1701 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const 1702 { 1703 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip(); 1704 } 1705 1706 bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const 1707 { 1708 // Need this done first to determine overflow. 1709 ASSERT(!m_renderView->needsLayout()); 1710 if (isMainFrame()) 1711 return false; 1712 1713 if (!(m_compositingTriggers & ChromeClient::ScrollableInnerFrameTrigger)) 1714 return false; 1715 1716 FrameView* frameView = m_renderView->frameView(); 1717 return frameView->isScrollable(); 1718 } 1719 1720 bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const 1721 { 1722 if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger)) 1723 return false; 1724 1725 RenderStyle* style = renderer->style(); 1726 // Note that we ask the renderer if it has a transform, because the style may have transforms, 1727 // but the renderer may be an inline that doesn't suppport them. 1728 return renderer->hasTransform() && style->transform().has3DOperation(); 1729 } 1730 1731 bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const 1732 { 1733 if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && renderer->isVideo()) { 1734 HTMLMediaElement* media = toHTMLMediaElement(renderer->node()); 1735 if (media->isFullscreen()) 1736 return true; 1737 } 1738 1739 if (!(m_compositingTriggers & ChromeClient::VideoTrigger)) 1740 return false; 1741 1742 if (renderer->isVideo()) { 1743 RenderVideo* video = toRenderVideo(renderer); 1744 return video->shouldDisplayVideo() && canAccelerateVideoRendering(video); 1745 } 1746 return false; 1747 } 1748 1749 bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const 1750 { 1751 if (!(m_compositingTriggers & ChromeClient::CanvasTrigger)) 1752 return false; 1753 1754 if (renderer->isCanvas()) { 1755 HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node()); 1756 return canvas->renderingContext() && canvas->renderingContext()->isAccelerated(); 1757 } 1758 return false; 1759 } 1760 1761 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const 1762 { 1763 if (!(m_compositingTriggers & ChromeClient::PluginTrigger)) 1764 return false; 1765 1766 bool composite = renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing(); 1767 if (!composite) 1768 return false; 1769 1770 // FIXME: this seems bogus. If we don't know the layout position/size of the plugin yet, would't that be handled elsewhere? 1771 m_needsToRecomputeCompositingRequirements = true; 1772 1773 RenderWidget* pluginRenderer = toRenderWidget(renderer); 1774 // If we can't reliably know the size of the plugin yet, don't change compositing state. 1775 if (pluginRenderer->needsLayout()) 1776 return pluginRenderer->hasLayer() && pluginRenderer->layer()->hasCompositedLayerMapping(); 1777 1778 // Don't go into compositing mode if height or width are zero, or size is 1x1. 1779 IntRect contentBox = pixelSnappedIntRect(pluginRenderer->contentBoxRect()); 1780 return contentBox.height() * contentBox.width() > 1; 1781 } 1782 1783 bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const 1784 { 1785 if (!renderer->isRenderPart()) 1786 return false; 1787 1788 RenderPart* frameRenderer = toRenderPart(renderer); 1789 1790 if (!frameRenderer->requiresAcceleratedCompositing()) 1791 return false; 1792 1793 if (frameRenderer->node() && frameRenderer->node()->isFrameOwnerElement() && toHTMLFrameOwnerElement(frameRenderer->node())->contentFrame() && toHTMLFrameOwnerElement(frameRenderer->node())->contentFrame()->remotePlatformLayer()) 1794 return true; 1795 1796 // FIXME: this seems bogus. If we don't know the layout position/size of the frame yet, wouldn't that be handled elsehwere? 1797 m_needsToRecomputeCompositingRequirements = true; 1798 1799 RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer); 1800 if (!innerCompositor) 1801 return false; 1802 1803 // If we can't reliably know the size of the iframe yet, don't change compositing state. 1804 if (renderer->needsLayout()) 1805 return frameRenderer->hasLayer() && frameRenderer->layer()->hasCompositedLayerMapping(); 1806 1807 // Don't go into compositing mode if height or width are zero. 1808 IntRect contentBox = pixelSnappedIntRect(frameRenderer->contentBoxRect()); 1809 return contentBox.height() * contentBox.width() > 0; 1810 } 1811 1812 bool RenderLayerCompositor::requiresCompositingForBackfaceVisibilityHidden(RenderObject* renderer) const 1813 { 1814 return canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden; 1815 } 1816 1817 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const 1818 { 1819 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger)) 1820 return false; 1821 1822 if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled()) 1823 return renderer->animation().isRunningAcceleratableAnimationOnRenderer(renderer); 1824 1825 return shouldCompositeForActiveAnimations(*renderer); 1826 } 1827 1828 bool RenderLayerCompositor::requiresCompositingForTransition(RenderObject* renderer) const 1829 { 1830 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger)) 1831 return false; 1832 1833 if (Settings* settings = m_renderView->document().settings()) { 1834 if (!settings->acceleratedCompositingForTransitionEnabled()) 1835 return false; 1836 } 1837 1838 return renderer->style()->transitionForProperty(CSSPropertyOpacity) 1839 || renderer->style()->transitionForProperty(CSSPropertyWebkitFilter) 1840 || renderer->style()->transitionForProperty(CSSPropertyWebkitTransform); 1841 } 1842 1843 CompositingReasons RenderLayerCompositor::subtreeReasonsForCompositing(RenderObject* renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants) const 1844 { 1845 CompositingReasons subtreeReasons = CompositingReasonNone; 1846 1847 // FIXME: this seems to be a potentially different layer than the layer for which this was called. May not be an error, but is very confusing. 1848 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); 1849 1850 // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented 1851 // via compositing so that they also apply to those composited descdendants. 1852 if (hasCompositedDescendants) { 1853 if (layer->transform()) 1854 subtreeReasons |= CompositingReasonTransformWithCompositedDescendants; 1855 1856 if (layer->shouldIsolateCompositedDescendants()) { 1857 ASSERT(layer->stackingNode()->isStackingContext()); 1858 subtreeReasons |= CompositingReasonIsolateCompositedDescendants; 1859 } 1860 1861 // If the implementation of createsGroup changes, we need to be aware of that in this part of code. 1862 ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->hasFilter() || renderer->hasBlendMode()) == renderer->createsGroup()); 1863 if (renderer->isTransparent()) 1864 subtreeReasons |= CompositingReasonOpacityWithCompositedDescendants; 1865 if (renderer->hasMask()) 1866 subtreeReasons |= CompositingReasonMaskWithCompositedDescendants; 1867 if (renderer->hasFilter()) 1868 subtreeReasons |= CompositingReasonFilterWithCompositedDescendants; 1869 if (renderer->hasBlendMode()) 1870 subtreeReasons |= CompositingReasonBlendingWithCompositedDescendants; 1871 1872 if (renderer->hasReflection()) 1873 subtreeReasons |= CompositingReasonReflectionWithCompositedDescendants; 1874 1875 if (renderer->hasClipOrOverflowClip()) 1876 subtreeReasons |= CompositingReasonClipsCompositingDescendants; 1877 } 1878 1879 1880 // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that 1881 // will be affected by the preserve-3d or perspective. 1882 if (has3DTransformedDescendants) { 1883 if (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D) 1884 subtreeReasons |= CompositingReasonPreserve3D; 1885 1886 if (renderer->style()->hasPerspective()) 1887 subtreeReasons |= CompositingReasonPerspective; 1888 } 1889 1890 return subtreeReasons; 1891 } 1892 1893 bool RenderLayerCompositor::requiresCompositingForFilters(RenderObject* renderer) const 1894 { 1895 if (!(m_compositingTriggers & ChromeClient::FilterTrigger)) 1896 return false; 1897 1898 return renderer->hasFilter(); 1899 } 1900 1901 bool RenderLayerCompositor::requiresCompositingForOverflowScrollingParent(const RenderLayer* layer) const 1902 { 1903 return !!layer->scrollParent(); 1904 } 1905 1906 bool RenderLayerCompositor::requiresCompositingForOutOfFlowClipping(const RenderLayer* layer) const 1907 { 1908 return layer->compositorDrivenAcceleratedScrollingEnabled() && layer->isUnclippedDescendant(); 1909 } 1910 1911 bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const 1912 { 1913 // position:fixed elements that create their own stacking context (e.g. have an explicit z-index, 1914 // opacity, transform) can get their own composited layer. A stacking context is required otherwise 1915 // z-index and clipping will be broken. 1916 if (!renderer->isPositioned()) 1917 return false; 1918 1919 EPosition position = renderer->style()->position(); 1920 bool isFixed = renderer->isOutOfFlowPositioned() && position == FixedPosition; 1921 if (isFixed && !layer->stackingNode()->isStackingContainer()) 1922 return false; 1923 1924 bool isSticky = renderer->isInFlowPositioned() && position == StickyPosition; 1925 if (!isFixed && !isSticky) 1926 return false; 1927 1928 // FIXME: acceleratedCompositingForFixedPositionEnabled should probably be renamed acceleratedCompositingForViewportConstrainedPositionEnabled(). 1929 if (Settings* settings = m_renderView->document().settings()) { 1930 if (!settings->acceleratedCompositingForFixedPositionEnabled()) 1931 return false; 1932 } 1933 1934 if (isSticky) 1935 return true; 1936 1937 RenderObject* container = renderer->container(); 1938 // If the renderer is not hooked up yet then we have to wait until it is. 1939 if (!container) { 1940 m_needsToRecomputeCompositingRequirements = true; 1941 return false; 1942 } 1943 1944 // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements. 1945 // They will stay fixed wrt the container rather than the enclosing frame. 1946 if (container != m_renderView) { 1947 if (viewportConstrainedNotCompositedReason) 1948 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNonViewContainer; 1949 return false; 1950 } 1951 1952 // If the fixed-position element does not have any scrollable ancestor between it and 1953 // its container, then we do not need to spend compositor resources for it. Start by 1954 // assuming we can opt-out (i.e. no scrollable ancestor), and refine the answer below. 1955 bool hasScrollableAncestor = false; 1956 1957 // The FrameView has the scrollbars associated with the top level viewport, so we have to 1958 // check the FrameView in addition to the hierarchy of ancestors. 1959 FrameView* frameView = m_renderView->frameView(); 1960 if (frameView && frameView->isScrollable()) 1961 hasScrollableAncestor = true; 1962 1963 RenderLayer* ancestor = layer->parent(); 1964 while (ancestor && !hasScrollableAncestor) { 1965 if (frameView->containsScrollableArea(ancestor->scrollableArea())) 1966 hasScrollableAncestor = true; 1967 if (ancestor->renderer() == m_renderView) 1968 break; 1969 ancestor = ancestor->parent(); 1970 } 1971 1972 if (!hasScrollableAncestor) { 1973 if (viewportConstrainedNotCompositedReason) 1974 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForUnscrollableAncestors; 1975 return false; 1976 } 1977 1978 // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done. 1979 if (!m_inPostLayoutUpdate) { 1980 m_needsToRecomputeCompositingRequirements = true; 1981 return layer->hasCompositedLayerMapping(); 1982 } 1983 1984 bool paintsContent = layer->isVisuallyNonEmpty() || layer->hasVisibleDescendant(); 1985 if (!paintsContent) { 1986 if (viewportConstrainedNotCompositedReason) 1987 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNoVisibleContent; 1988 return false; 1989 } 1990 1991 // Fixed position elements that are invisible in the current view don't get their own layer. 1992 if (FrameView* frameView = m_renderView->frameView()) { 1993 LayoutRect viewBounds = frameView->viewportConstrainedVisibleContentRect(); 1994 LayoutRect layerBounds = layer->calculateLayerBounds(rootRenderLayer(), 0, 1995 RenderLayer::DefaultCalculateLayerBoundsFlags 1996 | RenderLayer::ExcludeHiddenDescendants 1997 | RenderLayer::DontConstrainForMask 1998 | RenderLayer::IncludeCompositedDescendants 1999 | RenderLayer::PretendLayerHasOwnBacking); 2000 if (!viewBounds.intersects(enclosingIntRect(layerBounds))) { 2001 if (viewportConstrainedNotCompositedReason) { 2002 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView; 2003 m_needsToRecomputeCompositingRequirements = true; 2004 } 2005 return false; 2006 } 2007 } 2008 2009 return true; 2010 } 2011 2012 bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const RenderLayer* layer) const 2013 { 2014 return layer->needsCompositedScrolling(); 2015 } 2016 2017 bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderObject* renderer) const 2018 { 2019 if (!(m_compositingTriggers & ChromeClient::AnimationTrigger)) 2020 return false; 2021 if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled()) 2022 return renderer->animation().isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform); 2023 return hasActiveAnimations(*renderer, CSSPropertyWebkitTransform); 2024 } 2025 2026 // If an element has negative z-index children, those children render in front of the 2027 // layer background, so we need an extra 'contents' layer for the foreground of the layer 2028 // object. 2029 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const 2030 { 2031 return layer->stackingNode()->hasNegativeZOrderList(); 2032 } 2033 2034 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip) 2035 { 2036 if (!scrollbar) 2037 return; 2038 2039 context.save(); 2040 const IntRect& scrollbarRect = scrollbar->frameRect(); 2041 context.translate(-scrollbarRect.x(), -scrollbarRect.y()); 2042 IntRect transformedClip = clip; 2043 transformedClip.moveBy(scrollbarRect.location()); 2044 scrollbar->paint(&context, transformedClip); 2045 context.restore(); 2046 } 2047 2048 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip) 2049 { 2050 if (graphicsLayer == layerForHorizontalScrollbar()) 2051 paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip); 2052 else if (graphicsLayer == layerForVerticalScrollbar()) 2053 paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip); 2054 else if (graphicsLayer == layerForScrollCorner()) { 2055 const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect(); 2056 context.save(); 2057 context.translate(-scrollCorner.x(), -scrollCorner.y()); 2058 IntRect transformedClip = clip; 2059 transformedClip.moveBy(scrollCorner.location()); 2060 m_renderView->frameView()->paintScrollCorner(&context, transformedClip); 2061 context.restore(); 2062 } 2063 } 2064 2065 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const 2066 { 2067 if (Settings* settings = m_renderView->document().settings()) { 2068 if (settings->acceleratedCompositingForFixedRootBackgroundEnabled()) 2069 return true; 2070 } 2071 return false; 2072 } 2073 2074 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const 2075 { 2076 if (layer != m_renderView->layer()) 2077 return false; 2078 2079 return supportsFixedRootBackgroundCompositing() && m_renderView->rootBackgroundIsEntirelyFixed(); 2080 } 2081 2082 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const 2083 { 2084 // Get the fixed root background from the RenderView layer's compositedLayerMapping. 2085 RenderLayer* viewLayer = m_renderView->layer(); 2086 if (!viewLayer) 2087 return 0; 2088 2089 if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground()) 2090 return viewLayer->compositedLayerMapping()->backgroundLayer(); 2091 2092 return 0; 2093 } 2094 2095 static void resetTrackedRepaintRectsRecursive(GraphicsLayer* graphicsLayer) 2096 { 2097 if (!graphicsLayer) 2098 return; 2099 2100 graphicsLayer->resetTrackedRepaints(); 2101 2102 for (size_t i = 0; i < graphicsLayer->children().size(); ++i) 2103 resetTrackedRepaintRectsRecursive(graphicsLayer->children()[i]); 2104 2105 if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer()) 2106 resetTrackedRepaintRectsRecursive(replicaLayer); 2107 2108 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer()) 2109 resetTrackedRepaintRectsRecursive(maskLayer); 2110 2111 if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLayer()) 2112 resetTrackedRepaintRectsRecursive(clippingMaskLayer); 2113 } 2114 2115 void RenderLayerCompositor::resetTrackedRepaintRects() 2116 { 2117 if (GraphicsLayer* rootLayer = rootGraphicsLayer()) 2118 resetTrackedRepaintRectsRecursive(rootLayer); 2119 } 2120 2121 void RenderLayerCompositor::setTracksRepaints(bool tracksRepaints) 2122 { 2123 updateCompositingLayers(CompositingUpdateFinishAllDeferredWork); 2124 m_isTrackingRepaints = tracksRepaints; 2125 } 2126 2127 bool RenderLayerCompositor::isTrackingRepaints() const 2128 { 2129 return m_isTrackingRepaints; 2130 } 2131 2132 void RenderLayerCompositor::didCommitChangesForLayer(const GraphicsLayer*) const 2133 { 2134 // Nothing to do here yet. 2135 } 2136 2137 static bool shouldCompositeOverflowControls(FrameView* view) 2138 { 2139 if (Page* page = view->frame().page()) { 2140 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) 2141 if (scrollingCoordinator->coordinatesScrollingForFrameView(view)) 2142 return true; 2143 } 2144 2145 return true; 2146 } 2147 2148 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const 2149 { 2150 FrameView* view = m_renderView->frameView(); 2151 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar(); 2152 } 2153 2154 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const 2155 { 2156 FrameView* view = m_renderView->frameView(); 2157 return shouldCompositeOverflowControls(view) && view->verticalScrollbar(); 2158 } 2159 2160 bool RenderLayerCompositor::requiresScrollCornerLayer() const 2161 { 2162 FrameView* view = m_renderView->frameView(); 2163 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible(); 2164 } 2165 2166 #if USE(RUBBER_BANDING) 2167 bool RenderLayerCompositor::requiresOverhangLayers() const 2168 { 2169 // We don't want a layer if this is a subframe. 2170 if (!isMainFrame()) 2171 return false; 2172 2173 // We do want a layer if we have a scrolling coordinator and can scroll. 2174 if (scrollingCoordinator() && m_renderView->frameView()->hasOpaqueBackground()) 2175 return true; 2176 2177 // Chromium always wants a layer. 2178 return true; 2179 } 2180 #endif 2181 2182 void RenderLayerCompositor::updateOverflowControlsLayers() 2183 { 2184 #if USE(RUBBER_BANDING) 2185 if (requiresOverhangLayers()) { 2186 if (!m_layerForOverhangShadow) { 2187 m_layerForOverhangShadow = GraphicsLayer::create(graphicsLayerFactory(), this); 2188 OverscrollTheme::theme()->setUpOverhangShadowLayer(m_layerForOverhangShadow.get()); 2189 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get()); 2190 m_scrollLayer->addChild(m_layerForOverhangShadow.get()); 2191 } 2192 } else { 2193 if (m_layerForOverhangShadow) { 2194 m_layerForOverhangShadow->removeFromParent(); 2195 m_layerForOverhangShadow = nullptr; 2196 } 2197 } 2198 #endif 2199 2200 if (requiresHorizontalScrollbarLayer()) { 2201 if (!m_layerForHorizontalScrollbar) { 2202 m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this); 2203 m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get()); 2204 2205 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2206 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar); 2207 } 2208 } else if (m_layerForHorizontalScrollbar) { 2209 m_layerForHorizontalScrollbar->removeFromParent(); 2210 m_layerForHorizontalScrollbar = nullptr; 2211 2212 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2213 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar); 2214 } 2215 2216 if (requiresVerticalScrollbarLayer()) { 2217 if (!m_layerForVerticalScrollbar) { 2218 m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this); 2219 m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get()); 2220 2221 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2222 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar); 2223 } 2224 } else if (m_layerForVerticalScrollbar) { 2225 m_layerForVerticalScrollbar->removeFromParent(); 2226 m_layerForVerticalScrollbar = nullptr; 2227 2228 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2229 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar); 2230 } 2231 2232 if (requiresScrollCornerLayer()) { 2233 if (!m_layerForScrollCorner) { 2234 m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this); 2235 m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get()); 2236 } 2237 } else if (m_layerForScrollCorner) { 2238 m_layerForScrollCorner->removeFromParent(); 2239 m_layerForScrollCorner = nullptr; 2240 } 2241 2242 m_renderView->frameView()->positionScrollbarLayers(); 2243 } 2244 2245 void RenderLayerCompositor::ensureRootLayer() 2246 { 2247 RootLayerAttachment expectedAttachment = isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; 2248 if (expectedAttachment == m_rootLayerAttachment) 2249 return; 2250 2251 if (!m_rootContentLayer) { 2252 m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 2253 IntRect overflowRect = m_renderView->pixelSnappedLayoutOverflowRect(); 2254 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY())); 2255 m_rootContentLayer->setPosition(FloatPoint()); 2256 2257 // Need to clip to prevent transformed content showing outside this frame 2258 m_rootContentLayer->setMasksToBounds(true); 2259 } 2260 2261 if (!m_overflowControlsHostLayer) { 2262 ASSERT(!m_scrollLayer); 2263 ASSERT(!m_containerLayer); 2264 2265 // Create a layer to host the clipping layer and the overflow controls layers. 2266 m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 2267 2268 // Create a clipping layer if this is an iframe or settings require to clip. 2269 m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 2270 bool containerMasksToBounds = !isMainFrame(); 2271 if (Settings* settings = m_renderView->document().settings()) { 2272 if (settings->mainFrameClipsContent()) 2273 containerMasksToBounds = true; 2274 } 2275 m_containerLayer->setMasksToBounds(containerMasksToBounds); 2276 2277 m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 2278 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2279 scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true); 2280 2281 // Hook them up 2282 m_overflowControlsHostLayer->addChild(m_containerLayer.get()); 2283 m_containerLayer->addChild(m_scrollLayer.get()); 2284 m_scrollLayer->addChild(m_rootContentLayer.get()); 2285 2286 frameViewDidChangeSize(); 2287 frameViewDidScroll(); 2288 } 2289 2290 // Check to see if we have to change the attachment 2291 if (m_rootLayerAttachment != RootLayerUnattached) 2292 detachRootLayer(); 2293 2294 attachRootLayer(expectedAttachment); 2295 } 2296 2297 void RenderLayerCompositor::destroyRootLayer() 2298 { 2299 if (!m_rootContentLayer) 2300 return; 2301 2302 detachRootLayer(); 2303 2304 #if USE(RUBBER_BANDING) 2305 if (m_layerForOverhangShadow) { 2306 m_layerForOverhangShadow->removeFromParent(); 2307 m_layerForOverhangShadow = nullptr; 2308 } 2309 #endif 2310 2311 if (m_layerForHorizontalScrollbar) { 2312 m_layerForHorizontalScrollbar->removeFromParent(); 2313 m_layerForHorizontalScrollbar = nullptr; 2314 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2315 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar); 2316 if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar()) 2317 m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size())); 2318 } 2319 2320 if (m_layerForVerticalScrollbar) { 2321 m_layerForVerticalScrollbar->removeFromParent(); 2322 m_layerForVerticalScrollbar = nullptr; 2323 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 2324 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar); 2325 if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar()) 2326 m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size())); 2327 } 2328 2329 if (m_layerForScrollCorner) { 2330 m_layerForScrollCorner = nullptr; 2331 m_renderView->frameView()->invalidateScrollCorner(m_renderView->frameView()->scrollCornerRect()); 2332 } 2333 2334 if (m_overflowControlsHostLayer) { 2335 m_overflowControlsHostLayer = nullptr; 2336 m_containerLayer = nullptr; 2337 m_scrollLayer = nullptr; 2338 } 2339 ASSERT(!m_scrollLayer); 2340 m_rootContentLayer = nullptr; 2341 } 2342 2343 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment) 2344 { 2345 if (!m_rootContentLayer) 2346 return; 2347 2348 switch (attachment) { 2349 case RootLayerUnattached: 2350 ASSERT_NOT_REACHED(); 2351 break; 2352 case RootLayerAttachedViaChromeClient: { 2353 Frame& frame = m_renderView->frameView()->frame(); 2354 Page* page = frame.page(); 2355 if (!page) 2356 return; 2357 page->chrome().client().attachRootGraphicsLayer(&frame, rootGraphicsLayer()); 2358 break; 2359 } 2360 case RootLayerAttachedViaEnclosingFrame: { 2361 // The layer will get hooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration() 2362 // for the frame's renderer in the parent document. 2363 m_renderView->document().ownerElement()->scheduleLayerUpdate(); 2364 break; 2365 } 2366 } 2367 2368 m_rootLayerAttachment = attachment; 2369 } 2370 2371 void RenderLayerCompositor::detachRootLayer() 2372 { 2373 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached) 2374 return; 2375 2376 switch (m_rootLayerAttachment) { 2377 case RootLayerAttachedViaEnclosingFrame: { 2378 // The layer will get unhooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration() 2379 // for the frame's renderer in the parent document. 2380 if (m_overflowControlsHostLayer) 2381 m_overflowControlsHostLayer->removeFromParent(); 2382 else 2383 m_rootContentLayer->removeFromParent(); 2384 2385 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document().ownerElement()) 2386 ownerElement->scheduleLayerUpdate(); 2387 break; 2388 } 2389 case RootLayerAttachedViaChromeClient: { 2390 Frame& frame = m_renderView->frameView()->frame(); 2391 Page* page = frame.page(); 2392 if (!page) 2393 return; 2394 page->chrome().client().attachRootGraphicsLayer(&frame, 0); 2395 } 2396 break; 2397 case RootLayerUnattached: 2398 break; 2399 } 2400 2401 m_rootLayerAttachment = RootLayerUnattached; 2402 } 2403 2404 void RenderLayerCompositor::updateRootLayerAttachment() 2405 { 2406 ensureRootLayer(); 2407 } 2408 2409 bool RenderLayerCompositor::isMainFrame() const 2410 { 2411 // FIXME: Frame::isMainFrame() is probably better. 2412 return !m_renderView->document().ownerElement(); 2413 } 2414 2415 // IFrames are special, because we hook compositing layers together across iframe boundaries 2416 // when both parent and iframe content are composited. So when this frame becomes composited, we have 2417 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite. 2418 void RenderLayerCompositor::notifyIFramesOfCompositingChange() 2419 { 2420 if (!m_renderView->frameView()) 2421 return; 2422 Frame& frame = m_renderView->frameView()->frame(); 2423 2424 for (Frame* child = frame.tree().firstChild(); child; child = child->tree().traverseNext(&frame)) { 2425 if (child->document() && child->document()->ownerElement()) 2426 child->document()->ownerElement()->scheduleLayerUpdate(); 2427 } 2428 2429 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so 2430 // we need to schedule a style recalc in our parent document. 2431 if (HTMLFrameOwnerElement* ownerElement = m_renderView->document().ownerElement()) 2432 ownerElement->scheduleLayerUpdate(); 2433 } 2434 2435 bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const 2436 { 2437 const RenderStyle* style = layer->renderer()->style(); 2438 RenderLayerStackingNode* stackingNode = const_cast<RenderLayer*>(layer)->stackingNode(); 2439 2440 if (style && 2441 (style->transformStyle3D() == TransformStyle3DPreserve3D || 2442 style->hasPerspective() || 2443 style->transform().has3DOperation())) 2444 return true; 2445 2446 stackingNode->updateLayerListsIfNeeded(); 2447 2448 #if !ASSERT_DISABLED 2449 LayerListMutationDetector mutationChecker(stackingNode); 2450 #endif 2451 2452 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren); 2453 while (RenderLayerStackingNode* curNode = iterator.next()) { 2454 if (layerHas3DContent(curNode->layer())) 2455 return true; 2456 } 2457 2458 return false; 2459 } 2460 2461 static bool isRootmostFixedOrStickyLayer(RenderLayer* layer) 2462 { 2463 if (layer->renderer()->isStickyPositioned()) 2464 return true; 2465 2466 if (layer->renderer()->style()->position() != FixedPosition) 2467 return false; 2468 2469 for (RenderLayerStackingNode* stackingContainerNode = layer->stackingNode()->ancestorStackingContainerNode(); stackingContainerNode; stackingContainerNode = stackingContainerNode->ancestorStackingContainerNode()) { 2470 if (stackingContainerNode->layer()->hasCompositedLayerMapping() && stackingContainerNode->layer()->renderer()->style()->position() == FixedPosition) 2471 return false; 2472 } 2473 2474 return true; 2475 } 2476 2477 void RenderLayerCompositor::updateViewportConstraintStatus(RenderLayer* layer) 2478 { 2479 if (isRootmostFixedOrStickyLayer(layer)) 2480 addViewportConstrainedLayer(layer); 2481 else 2482 removeViewportConstrainedLayer(layer); 2483 } 2484 2485 void RenderLayerCompositor::addViewportConstrainedLayer(RenderLayer* layer) 2486 { 2487 m_viewportConstrainedLayers.add(layer); 2488 } 2489 2490 void RenderLayerCompositor::removeViewportConstrainedLayer(RenderLayer* layer) 2491 { 2492 if (!m_viewportConstrainedLayers.contains(layer)) 2493 return; 2494 2495 m_viewportConstrainedLayers.remove(layer); 2496 } 2497 2498 FixedPositionViewportConstraints RenderLayerCompositor::computeFixedViewportConstraints(RenderLayer* layer) const 2499 { 2500 ASSERT(layer->hasCompositedLayerMapping()); 2501 2502 FrameView* frameView = m_renderView->frameView(); 2503 LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect(); 2504 2505 FixedPositionViewportConstraints constraints; 2506 2507 GraphicsLayer* graphicsLayer = layer->compositedLayerMapping()->mainGraphicsLayer(); 2508 2509 constraints.setLayerPositionAtLastLayout(graphicsLayer->position()); 2510 constraints.setViewportRectAtLastLayout(viewportRect); 2511 2512 RenderStyle* style = layer->renderer()->style(); 2513 if (!style->left().isAuto()) 2514 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft); 2515 2516 if (!style->right().isAuto()) 2517 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight); 2518 2519 if (!style->top().isAuto()) 2520 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop); 2521 2522 if (!style->bottom().isAuto()) 2523 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom); 2524 2525 // If left and right are auto, use left. 2526 if (style->left().isAuto() && style->right().isAuto()) 2527 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft); 2528 2529 // If top and bottom are auto, use top. 2530 if (style->top().isAuto() && style->bottom().isAuto()) 2531 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop); 2532 2533 return constraints; 2534 } 2535 2536 StickyPositionViewportConstraints RenderLayerCompositor::computeStickyViewportConstraints(RenderLayer* layer) const 2537 { 2538 ASSERT(layer->hasCompositedLayerMapping()); 2539 2540 FrameView* frameView = m_renderView->frameView(); 2541 LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect(); 2542 2543 StickyPositionViewportConstraints constraints; 2544 2545 RenderBoxModelObject* renderer = toRenderBoxModelObject(layer->renderer()); 2546 2547 renderer->computeStickyPositionConstraints(constraints, viewportRect); 2548 2549 GraphicsLayer* graphicsLayer = layer->compositedLayerMapping()->mainGraphicsLayer(); 2550 2551 constraints.setLayerPositionAtLastLayout(graphicsLayer->position()); 2552 constraints.setStickyOffsetAtLastLayout(renderer->stickyPositionOffset()); 2553 2554 return constraints; 2555 } 2556 2557 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const 2558 { 2559 if (Page* page = this->page()) 2560 return page->scrollingCoordinator(); 2561 2562 return 0; 2563 } 2564 2565 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const 2566 { 2567 if (Page* page = this->page()) 2568 return page->chrome().client().graphicsLayerFactory(); 2569 return 0; 2570 } 2571 2572 Page* RenderLayerCompositor::page() const 2573 { 2574 return m_renderView->frameView()->frame().page(); 2575 } 2576 2577 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer) 2578 { 2579 String name; 2580 if (graphicsLayer == m_rootContentLayer.get()) { 2581 name = "Content Root Layer"; 2582 #if USE(RUBBER_BANDING) 2583 } else if (graphicsLayer == m_layerForOverhangShadow.get()) { 2584 name = "Overhang Areas Shadow"; 2585 #endif 2586 } else if (graphicsLayer == m_overflowControlsHostLayer.get()) { 2587 name = "Overflow Controls Host Layer"; 2588 } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) { 2589 name = "Horizontal Scrollbar Layer"; 2590 } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) { 2591 name = "Vertical Scrollbar Layer"; 2592 } else if (graphicsLayer == m_layerForScrollCorner.get()) { 2593 name = "Scroll Corner Layer"; 2594 } else if (graphicsLayer == m_containerLayer.get()) { 2595 name = "Frame Clipping Layer"; 2596 } else if (graphicsLayer == m_scrollLayer.get()) { 2597 name = "Frame Scrolling Layer"; 2598 } else { 2599 ASSERT_NOT_REACHED(); 2600 } 2601 2602 return name; 2603 } 2604 2605 } // namespace WebCore 2606