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/compositing/RenderLayerCompositor.h" 29 30 #include "core/animation/DocumentAnimations.h" 31 #include "core/dom/Fullscreen.h" 32 #include "core/frame/FrameView.h" 33 #include "core/frame/LocalFrame.h" 34 #include "core/frame/Settings.h" 35 #include "core/html/HTMLIFrameElement.h" 36 #include "core/inspector/InspectorInstrumentation.h" 37 #include "core/inspector/InspectorNodeIds.h" 38 #include "core/page/Chrome.h" 39 #include "core/page/ChromeClient.h" 40 #include "core/page/Page.h" 41 #include "core/page/scrolling/ScrollingCoordinator.h" 42 #include "core/rendering/RenderEmbeddedObject.h" 43 #include "core/rendering/RenderLayerStackingNode.h" 44 #include "core/rendering/RenderLayerStackingNodeIterator.h" 45 #include "core/rendering/RenderPart.h" 46 #include "core/rendering/RenderVideo.h" 47 #include "core/rendering/RenderView.h" 48 #include "core/rendering/compositing/CompositedLayerMapping.h" 49 #include "core/rendering/compositing/CompositingInputsUpdater.h" 50 #include "core/rendering/compositing/CompositingLayerAssigner.h" 51 #include "core/rendering/compositing/CompositingRequirementsUpdater.h" 52 #include "core/rendering/compositing/GraphicsLayerTreeBuilder.h" 53 #include "core/rendering/compositing/GraphicsLayerUpdater.h" 54 #include "platform/OverscrollTheme.h" 55 #include "platform/RuntimeEnabledFeatures.h" 56 #include "platform/ScriptForbiddenScope.h" 57 #include "platform/TraceEvent.h" 58 #include "platform/graphics/GraphicsLayer.h" 59 #include "public/platform/Platform.h" 60 61 namespace blink { 62 63 RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView) 64 : m_renderView(renderView) 65 , m_compositingReasonFinder(renderView) 66 , m_pendingUpdateType(CompositingUpdateNone) 67 , m_hasAcceleratedCompositing(true) 68 , m_compositing(false) 69 , m_rootShouldAlwaysCompositeDirty(true) 70 , m_needsUpdateFixedBackground(false) 71 , m_isTrackingPaintInvalidations(false) 72 , m_rootLayerAttachment(RootLayerUnattached) 73 , m_inOverlayFullscreenVideo(false) 74 { 75 updateAcceleratedCompositingSettings(); 76 } 77 78 RenderLayerCompositor::~RenderLayerCompositor() 79 { 80 ASSERT(m_rootLayerAttachment == RootLayerUnattached); 81 } 82 83 bool RenderLayerCompositor::inCompositingMode() const 84 { 85 // FIXME: This should assert that lificycle is >= CompositingClean since 86 // the last step of updateIfNeeded can set this bit to false. 87 ASSERT(!m_rootShouldAlwaysCompositeDirty); 88 return m_compositing; 89 } 90 91 bool RenderLayerCompositor::staleInCompositingMode() const 92 { 93 return m_compositing; 94 } 95 96 void RenderLayerCompositor::setCompositingModeEnabled(bool enable) 97 { 98 if (enable == m_compositing) 99 return; 100 101 m_compositing = enable; 102 103 // RenderPart::requiresAcceleratedCompositing is used to determine self-paintingness 104 // and bases it's return value for frames on the m_compositing bit here. 105 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) { 106 if (RenderPart* renderer = ownerElement->renderPart()) 107 renderer->layer()->updateSelfPaintingLayer(); 108 } 109 110 if (m_compositing) 111 ensureRootLayer(); 112 else 113 destroyRootLayer(); 114 115 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so 116 // we need to schedule a style recalc in our parent document. 117 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) 118 ownerElement->setNeedsCompositingUpdate(); 119 } 120 121 void RenderLayerCompositor::enableCompositingModeIfNeeded() 122 { 123 if (!m_rootShouldAlwaysCompositeDirty) 124 return; 125 126 m_rootShouldAlwaysCompositeDirty = false; 127 if (m_compositing) 128 return; 129 130 if (rootShouldAlwaysComposite()) { 131 // FIXME: Is this needed? It was added in https://bugs.webkit.org/show_bug.cgi?id=26651. 132 // No tests fail if it's deleted. 133 setNeedsCompositingUpdate(CompositingUpdateRebuildTree); 134 setCompositingModeEnabled(true); 135 } 136 } 137 138 bool RenderLayerCompositor::rootShouldAlwaysComposite() const 139 { 140 if (!m_hasAcceleratedCompositing) 141 return false; 142 return m_renderView.frame()->isLocalRoot() || m_compositingReasonFinder.requiresCompositingForScrollableFrame(); 143 } 144 145 void RenderLayerCompositor::updateAcceleratedCompositingSettings() 146 { 147 m_compositingReasonFinder.updateTriggers(); 148 m_hasAcceleratedCompositing = m_renderView.document().settings()->acceleratedCompositingEnabled(); 149 m_rootShouldAlwaysCompositeDirty = true; 150 } 151 152 bool RenderLayerCompositor::layerSquashingEnabled() const 153 { 154 if (!RuntimeEnabledFeatures::layerSquashingEnabled()) 155 return false; 156 if (Settings* settings = m_renderView.document().settings()) 157 return settings->layerSquashingEnabled(); 158 return true; 159 } 160 161 bool RenderLayerCompositor::preferCompositingToLCDTextEnabled() const 162 { 163 return m_compositingReasonFinder.hasOverflowScrollTrigger(); 164 } 165 166 static RenderVideo* findFullscreenVideoRenderer(Document& document) 167 { 168 // Recursively find the document that is in fullscreen. 169 Element* fullscreenElement = Fullscreen::fullscreenElementFrom(document); 170 Document* contentDocument = &document; 171 while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) { 172 contentDocument = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument(); 173 if (!contentDocument) 174 return 0; 175 fullscreenElement = Fullscreen::fullscreenElementFrom(*contentDocument); 176 } 177 // Get the current fullscreen element from the document. 178 fullscreenElement = Fullscreen::currentFullScreenElementFrom(*contentDocument); 179 if (!isHTMLVideoElement(fullscreenElement)) 180 return 0; 181 RenderObject* renderer = fullscreenElement->renderer(); 182 if (!renderer) 183 return 0; 184 return toRenderVideo(renderer); 185 } 186 187 void RenderLayerCompositor::updateIfNeededRecursive() 188 { 189 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) { 190 if (child->isLocalFrame()) 191 toLocalFrame(child)->contentRenderer()->compositor()->updateIfNeededRecursive(); 192 } 193 194 TRACE_EVENT0("blink", "RenderLayerCompositor::updateIfNeededRecursive"); 195 196 ASSERT(!m_renderView.needsLayout()); 197 198 ScriptForbiddenScope forbidScript; 199 200 // FIXME: enableCompositingModeIfNeeded can trigger a CompositingUpdateRebuildTree, 201 // which asserts that it's not InCompositingUpdate. 202 enableCompositingModeIfNeeded(); 203 204 rootRenderLayer()->updateDescendantDependentFlagsForEntireSubtree(); 205 206 lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate); 207 updateIfNeeded(); 208 lifecycle().advanceTo(DocumentLifecycle::CompositingClean); 209 210 DocumentAnimations::startPendingAnimations(m_renderView.document()); 211 212 #if ENABLE(ASSERT) 213 ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean); 214 assertNoUnresolvedDirtyBits(); 215 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) { 216 if (child->isLocalFrame()) 217 toLocalFrame(child)->contentRenderer()->compositor()->assertNoUnresolvedDirtyBits(); 218 } 219 #endif 220 } 221 222 void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType updateType) 223 { 224 ASSERT(updateType != CompositingUpdateNone); 225 m_pendingUpdateType = std::max(m_pendingUpdateType, updateType); 226 page()->animator().scheduleVisualUpdate(); 227 lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean); 228 } 229 230 void RenderLayerCompositor::didLayout() 231 { 232 // FIXME: Technically we only need to do this when the FrameView's 233 // isScrollable method would return a different value. 234 m_rootShouldAlwaysCompositeDirty = true; 235 enableCompositingModeIfNeeded(); 236 237 // FIXME: Rather than marking the entire RenderView as dirty, we should 238 // track which RenderLayers moved during layout and only dirty those 239 // specific RenderLayers. 240 rootRenderLayer()->setNeedsCompositingInputsUpdate(); 241 } 242 243 #if ENABLE(ASSERT) 244 245 void RenderLayerCompositor::assertNoUnresolvedDirtyBits() 246 { 247 ASSERT(m_pendingUpdateType == CompositingUpdateNone); 248 ASSERT(!m_rootShouldAlwaysCompositeDirty); 249 } 250 251 #endif 252 253 void RenderLayerCompositor::applyOverlayFullscreenVideoAdjustment() 254 { 255 m_inOverlayFullscreenVideo = false; 256 if (!m_rootContentLayer) 257 return; 258 259 bool isLocalRoot = m_renderView.frame()->isLocalRoot(); 260 RenderVideo* video = findFullscreenVideoRenderer(m_renderView.document()); 261 if (!video || !video->layer()->hasCompositedLayerMapping()) { 262 if (isLocalRoot) { 263 GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer(); 264 if (backgroundLayer && !backgroundLayer->parent()) 265 rootFixedBackgroundsChanged(); 266 } 267 return; 268 } 269 270 GraphicsLayer* videoLayer = video->layer()->compositedLayerMapping()->mainGraphicsLayer(); 271 272 // The fullscreen video has layer position equal to its enclosing frame's scroll position because fullscreen container is fixed-positioned. 273 // We should reset layer position here since we are going to reattach the layer at the very top level. 274 videoLayer->setPosition(IntPoint()); 275 276 // Only steal fullscreen video layer and clear all other layers if we are the main frame. 277 if (!isLocalRoot) 278 return; 279 280 m_rootContentLayer->removeAllChildren(); 281 m_overflowControlsHostLayer->addChild(videoLayer); 282 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer()) 283 backgroundLayer->removeFromParent(); 284 m_inOverlayFullscreenVideo = true; 285 } 286 287 void RenderLayerCompositor::updateWithoutAcceleratedCompositing(CompositingUpdateType updateType) 288 { 289 ASSERT(!hasAcceleratedCompositing()); 290 291 if (updateType >= CompositingUpdateAfterCompositingInputChange) 292 CompositingInputsUpdater(rootRenderLayer()).update(); 293 294 #if ENABLE(ASSERT) 295 CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(rootRenderLayer()); 296 #endif 297 } 298 299 static void forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(RenderObject* renderer) 300 { 301 // We clear the previous paint invalidation rect as it's wrong (paint invaliation container 302 // changed, ...). Forcing a full invalidation will make us recompute it. Also we are not 303 // changing the previous position from our paint invalidation container, which is fine as 304 // we want a full paint invalidation anyway. 305 renderer->setPreviousPaintInvalidationRect(LayoutRect()); 306 renderer->setShouldDoFullPaintInvalidation(true); 307 308 for (RenderObject* child = renderer->slowFirstChild(); child; child = child->nextSibling()) { 309 if (!child->isPaintInvalidationContainer()) 310 forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(child); 311 } 312 } 313 314 315 void RenderLayerCompositor::updateIfNeeded() 316 { 317 CompositingUpdateType updateType = m_pendingUpdateType; 318 m_pendingUpdateType = CompositingUpdateNone; 319 320 if (!hasAcceleratedCompositing()) { 321 updateWithoutAcceleratedCompositing(updateType); 322 return; 323 } 324 325 if (updateType == CompositingUpdateNone) 326 return; 327 328 RenderLayer* updateRoot = rootRenderLayer(); 329 330 Vector<RenderLayer*> layersNeedingPaintInvalidation; 331 332 if (updateType >= CompositingUpdateAfterCompositingInputChange) { 333 CompositingInputsUpdater(updateRoot).update(); 334 335 #if ENABLE(ASSERT) 336 // FIXME: Move this check to the end of the compositing update. 337 CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(updateRoot); 338 #endif 339 340 CompositingRequirementsUpdater(m_renderView, m_compositingReasonFinder).update(updateRoot); 341 342 CompositingLayerAssigner layerAssigner(this); 343 layerAssigner.assign(updateRoot, layersNeedingPaintInvalidation); 344 345 bool layersChanged = layerAssigner.layersChanged(); 346 347 { 348 TRACE_EVENT0("blink", "RenderLayerCompositor::updateAfterCompositingChange"); 349 if (const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.frameView()->scrollableAreas()) { 350 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it) 351 layersChanged |= (*it)->updateAfterCompositingChange(); 352 } 353 } 354 355 if (layersChanged) 356 updateType = std::max(updateType, CompositingUpdateRebuildTree); 357 } 358 359 if (updateType != CompositingUpdateNone) { 360 GraphicsLayerUpdater updater; 361 updater.update(*updateRoot, layersNeedingPaintInvalidation); 362 363 if (updater.needsRebuildTree()) 364 updateType = std::max(updateType, CompositingUpdateRebuildTree); 365 366 #if ENABLE(ASSERT) 367 // FIXME: Move this check to the end of the compositing update. 368 GraphicsLayerUpdater::assertNeedsToUpdateGraphicsLayerBitsCleared(*updateRoot); 369 #endif 370 } 371 372 if (updateType >= CompositingUpdateRebuildTree) { 373 GraphicsLayerTreeBuilder::AncestorInfo ancestorInfo; 374 GraphicsLayerVector childList; 375 ancestorInfo.childLayersOfEnclosingCompositedLayer = &childList; 376 { 377 TRACE_EVENT0("blink", "GraphicsLayerTreeBuilder::rebuild"); 378 GraphicsLayerTreeBuilder().rebuild(*updateRoot, ancestorInfo); 379 } 380 381 if (childList.isEmpty()) 382 destroyRootLayer(); 383 else 384 m_rootContentLayer->setChildren(childList); 385 386 if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled()) 387 applyOverlayFullscreenVideoAdjustment(); 388 } 389 390 if (m_needsUpdateFixedBackground) { 391 rootFixedBackgroundsChanged(); 392 m_needsUpdateFixedBackground = false; 393 } 394 395 for (unsigned i = 0; i < layersNeedingPaintInvalidation.size(); i++) 396 forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(layersNeedingPaintInvalidation[i]->renderer()); 397 398 // Inform the inspector that the layer tree has changed. 399 if (m_renderView.frame()->isMainFrame()) 400 InspectorInstrumentation::layerTreeDidChange(m_renderView.frame()); 401 } 402 403 bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer, const CompositingStateTransitionType compositedLayerUpdate) 404 { 405 bool compositedLayerMappingChanged = false; 406 407 // FIXME: It would be nice to directly use the layer's compositing reason, 408 // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing 409 // requirements fully. 410 switch (compositedLayerUpdate) { 411 case AllocateOwnCompositedLayerMapping: 412 ASSERT(!layer->hasCompositedLayerMapping()); 413 setCompositingModeEnabled(true); 414 415 // If we need to issue paint invalidations, do so before allocating the compositedLayerMapping and clearing out the groupedMapping. 416 paintInvalidationOnCompositingChange(layer); 417 418 // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so 419 // that computing paint invalidation rects will know the layer's correct compositingState. 420 // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping? 421 // Need to create a test where a squashed layer pops into compositing. And also to cover all other 422 // sorts of compositingState transitions. 423 layer->setLostGroupedMapping(false); 424 layer->setGroupedMapping(0); 425 426 layer->ensureCompositedLayerMapping(); 427 compositedLayerMappingChanged = true; 428 429 // At this time, the ScrollingCooridnator only supports the top-level frame. 430 if (layer->isRootLayer() && m_renderView.frame()->isLocalRoot()) { 431 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 432 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView()); 433 } 434 break; 435 case RemoveOwnCompositedLayerMapping: 436 // PutInSquashingLayer means you might have to remove the composited layer mapping first. 437 case PutInSquashingLayer: 438 if (layer->hasCompositedLayerMapping()) { 439 // If we're removing the compositedLayerMapping from a reflection, clear the source GraphicsLayer's pointer to 440 // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection 441 // are both either composited, or not composited. 442 if (layer->isReflection()) { 443 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer(); 444 if (sourceLayer->hasCompositedLayerMapping()) { 445 ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer()); 446 sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->setReplicatedByLayer(0); 447 } 448 } 449 450 layer->clearCompositedLayerMapping(); 451 compositedLayerMappingChanged = true; 452 } 453 454 break; 455 case RemoveFromSquashingLayer: 456 case NoCompositingStateChange: 457 // Do nothing. 458 break; 459 } 460 461 if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateRequiresOwnBackingStoreForIntrinsicReasons()) { 462 compositedLayerMappingChanged = true; 463 layer->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); 464 } 465 466 if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) { 467 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer())); 468 if (innerCompositor && innerCompositor->staleInCompositingMode()) 469 innerCompositor->updateRootLayerAttachment(); 470 } 471 472 if (compositedLayerMappingChanged) 473 layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects); 474 475 // If a fixed position layer gained/lost a compositedLayerMapping or the reason not compositing it changed, 476 // the scrolling coordinator needs to recalculate whether it can do fast scrolling. 477 if (compositedLayerMappingChanged) { 478 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 479 scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView.frameView()); 480 } 481 482 return compositedLayerMappingChanged; 483 } 484 485 void RenderLayerCompositor::paintInvalidationOnCompositingChange(RenderLayer* layer) 486 { 487 // If the renderer is not attached yet, no need to issue paint invalidations. 488 if (layer->renderer() != &m_renderView && !layer->renderer()->parent()) 489 return; 490 491 // For querying RenderLayer::compositingState() 492 // Eager invalidation here is correct, since we are invalidating with respect to the previous frame's 493 // compositing state when changing the compositing backing of the layer. 494 DisableCompositingQueryAsserts disabler; 495 496 layer->renderer()->invalidatePaintIncludingNonCompositingDescendants(); 497 } 498 499 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset) 500 { 501 if (m_overflowControlsHostLayer) 502 m_overflowControlsHostLayer->setPosition(contentsOffset); 503 } 504 505 void RenderLayerCompositor::frameViewDidChangeSize() 506 { 507 if (m_containerLayer) { 508 FrameView* frameView = m_renderView.frameView(); 509 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); 510 m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSize(IncludeScrollbars)); 511 512 frameViewDidScroll(); 513 updateOverflowControlsLayers(); 514 } 515 } 516 517 enum AcceleratedFixedRootBackgroundHistogramBuckets { 518 ScrolledMainFrameBucket = 0, 519 ScrolledMainFrameWithAcceleratedFixedRootBackground = 1, 520 ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2, 521 AcceleratedFixedRootBackgroundHistogramMax = 3 522 }; 523 524 void RenderLayerCompositor::frameViewDidScroll() 525 { 526 FrameView* frameView = m_renderView.frameView(); 527 IntPoint scrollPosition = frameView->scrollPosition(); 528 529 if (!m_scrollLayer) 530 return; 531 532 bool scrollingCoordinatorHandlesOffset = false; 533 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) { 534 if (Settings* settings = m_renderView.document().settings()) { 535 if (m_renderView.frame()->isLocalRoot() || settings->preferCompositingToLCDTextEnabled()) 536 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView); 537 } 538 } 539 540 // Scroll position = scroll minimum + scroll offset. Adjust the layer's 541 // position to handle whatever the scroll coordinator isn't handling. 542 // The minimum scroll position is non-zero for RTL pages with overflow. 543 if (scrollingCoordinatorHandlesOffset) 544 m_scrollLayer->setPosition(-frameView->minimumScrollPosition()); 545 else 546 m_scrollLayer->setPosition(-scrollPosition); 547 548 549 Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground", 550 ScrolledMainFrameBucket, 551 AcceleratedFixedRootBackgroundHistogramMax); 552 } 553 554 void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange() 555 { 556 if (m_containerLayer) 557 updateOverflowControlsLayers(); 558 } 559 560 void RenderLayerCompositor::rootFixedBackgroundsChanged() 561 { 562 if (!supportsFixedRootBackgroundCompositing()) 563 return; 564 565 // To avoid having to make the fixed root background layer fixed positioned to 566 // stay put, we position it in the layer tree as follows: 567 // 568 // + Overflow controls host 569 // + LocalFrame clip 570 // + (Fixed root background) <-- Here. 571 // + LocalFrame scroll 572 // + Root content layer 573 // + Scrollbars 574 // 575 // That is, it needs to be the first child of the frame clip, the sibling of 576 // the frame scroll layer. The compositor does not own the background layer, it 577 // just positions it (like the foreground layer). 578 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer()) 579 m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get()); 580 } 581 582 bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer) 583 { 584 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 585 return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea()); 586 return false; 587 } 588 589 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags) 590 { 591 ASSERT(lifecycle().state() >= DocumentLifecycle::PaintInvalidationClean); 592 593 if (!m_rootContentLayer) 594 return String(); 595 596 // We skip dumping the scroll and clip layers to keep layerTreeAsText output 597 // similar between platforms (unless we explicitly request dumping from the 598 // root. 599 GraphicsLayer* rootLayer = m_rootContentLayer.get(); 600 if (flags & LayerTreeIncludesRootLayer) 601 rootLayer = rootGraphicsLayer(); 602 603 String layerTreeText = rootLayer->layerTreeAsText(flags); 604 605 // The true root layer is not included in the dump, so if we want to report 606 // its paint invalidation rects, they must be included here. 607 if (flags & LayerTreeIncludesPaintInvalidationRects) 608 return m_renderView.frameView()->trackedPaintInvalidationRectsAsText() + layerTreeText; 609 610 return layerTreeText; 611 } 612 613 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer) 614 { 615 if (!renderer->node()->isFrameOwnerElement()) 616 return 0; 617 618 HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node()); 619 if (Document* contentDocument = element->contentDocument()) { 620 if (RenderView* view = contentDocument->renderView()) 621 return view->compositor(); 622 } 623 return 0; 624 } 625 626 // FIXME: What does this function do? It needs a clearer name. 627 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer) 628 { 629 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer); 630 if (!innerCompositor || !innerCompositor->staleInCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame) 631 return false; 632 633 RenderLayer* layer = renderer->layer(); 634 if (!layer->hasCompositedLayerMapping()) 635 return false; 636 637 CompositedLayerMapping* compositedLayerMapping = layer->compositedLayerMapping(); 638 GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers(); 639 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer(); 640 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) { 641 hostingLayer->removeAllChildren(); 642 hostingLayer->addChild(rootLayer); 643 } 644 return true; 645 } 646 647 static void fullyInvalidatePaintRecursive(RenderLayer* layer) 648 { 649 if (layer->compositingState() == PaintsIntoOwnBacking) { 650 layer->compositedLayerMapping()->setContentsNeedDisplay(); 651 layer->compositedLayerMapping()->setSquashingContentsNeedDisplay(); 652 } 653 654 for (RenderLayer* child = layer->firstChild(); child; child = child->nextSibling()) 655 fullyInvalidatePaintRecursive(child); 656 } 657 658 void RenderLayerCompositor::fullyInvalidatePaint() 659 { 660 // We're walking all compositing layers and invalidating them, so there's 661 // no need to have up-to-date compositing state. 662 DisableCompositingQueryAsserts disabler; 663 fullyInvalidatePaintRecursive(rootRenderLayer()); 664 } 665 666 RenderLayer* RenderLayerCompositor::rootRenderLayer() const 667 { 668 return m_renderView.layer(); 669 } 670 671 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const 672 { 673 if (m_overflowControlsHostLayer) 674 return m_overflowControlsHostLayer.get(); 675 return m_rootContentLayer.get(); 676 } 677 678 GraphicsLayer* RenderLayerCompositor::scrollLayer() const 679 { 680 return m_scrollLayer.get(); 681 } 682 683 GraphicsLayer* RenderLayerCompositor::containerLayer() const 684 { 685 return m_containerLayer.get(); 686 } 687 688 GraphicsLayer* RenderLayerCompositor::ensureRootTransformLayer() 689 { 690 ASSERT(rootGraphicsLayer()); 691 692 if (!m_rootTransformLayer.get()) { 693 m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 694 m_overflowControlsHostLayer->addChild(m_rootTransformLayer.get()); 695 m_rootTransformLayer->addChild(m_containerLayer.get()); 696 updateOverflowControlsLayers(); 697 } 698 699 return m_rootTransformLayer.get(); 700 } 701 702 void RenderLayerCompositor::setIsInWindow(bool isInWindow) 703 { 704 if (!staleInCompositingMode()) 705 return; 706 707 if (isInWindow) { 708 if (m_rootLayerAttachment != RootLayerUnattached) 709 return; 710 711 RootLayerAttachment attachment = m_renderView.frame()->isLocalRoot() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; 712 attachRootLayer(attachment); 713 } else { 714 if (m_rootLayerAttachment == RootLayerUnattached) 715 return; 716 717 detachRootLayer(); 718 } 719 } 720 721 void RenderLayerCompositor::updateRootLayerPosition() 722 { 723 if (m_rootContentLayer) { 724 const IntRect& documentRect = m_renderView.documentRect(); 725 m_rootContentLayer->setSize(documentRect.size()); 726 m_rootContentLayer->setPosition(documentRect.location()); 727 #if USE(RUBBER_BANDING) 728 if (m_layerForOverhangShadow) 729 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get()); 730 #endif 731 } 732 if (m_containerLayer) { 733 FrameView* frameView = m_renderView.frameView(); 734 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); 735 m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSize(IncludeScrollbars)); 736 } 737 } 738 739 void RenderLayerCompositor::updatePotentialCompositingReasonsFromStyle(RenderLayer* layer) 740 { 741 layer->setPotentialCompositingReasonsFromStyle(m_compositingReasonFinder.potentialCompositingReasonsFromStyle(layer->renderer())); 742 } 743 744 void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer) 745 { 746 layer->setCompositingReasons(m_compositingReasonFinder.directReasons(layer), CompositingReasonComboAllDirectReasons); 747 } 748 749 void RenderLayerCompositor::setOverlayLayer(GraphicsLayer* layer) 750 { 751 ASSERT(rootGraphicsLayer()); 752 753 if (layer->parent() != m_overflowControlsHostLayer.get()) 754 m_overflowControlsHostLayer->addChild(layer); 755 } 756 757 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const 758 { 759 // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly. 760 // See http://webkit.org/b/84900 to re-enable it. 761 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer->subtreeIsInvisible() && layer->renderer()->flowThreadState() == RenderObject::NotInsideFlowThread; 762 } 763 764 // Return true if the given layer is a stacking context and has compositing child 765 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer 766 // into the hierarchy between this layer and its children in the z-order hierarchy. 767 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const 768 { 769 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip(); 770 } 771 772 // If an element has composited negative z-index children, those children render in front of the 773 // layer background, so we need an extra 'contents' layer for the foreground of the layer 774 // object. 775 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const 776 { 777 if (!layer->hasCompositingDescendant()) 778 return false; 779 return layer->stackingNode()->hasNegativeZOrderList(); 780 } 781 782 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip) 783 { 784 if (!scrollbar) 785 return; 786 787 context.save(); 788 const IntRect& scrollbarRect = scrollbar->frameRect(); 789 context.translate(-scrollbarRect.x(), -scrollbarRect.y()); 790 IntRect transformedClip = clip; 791 transformedClip.moveBy(scrollbarRect.location()); 792 scrollbar->paint(&context, transformedClip); 793 context.restore(); 794 } 795 796 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip) 797 { 798 if (graphicsLayer == layerForHorizontalScrollbar()) 799 paintScrollbar(m_renderView.frameView()->horizontalScrollbar(), context, clip); 800 else if (graphicsLayer == layerForVerticalScrollbar()) 801 paintScrollbar(m_renderView.frameView()->verticalScrollbar(), context, clip); 802 else if (graphicsLayer == layerForScrollCorner()) { 803 const IntRect& scrollCorner = m_renderView.frameView()->scrollCornerRect(); 804 context.save(); 805 context.translate(-scrollCorner.x(), -scrollCorner.y()); 806 IntRect transformedClip = clip; 807 transformedClip.moveBy(scrollCorner.location()); 808 m_renderView.frameView()->paintScrollCorner(&context, transformedClip); 809 context.restore(); 810 } 811 } 812 813 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const 814 { 815 if (Settings* settings = m_renderView.document().settings()) 816 return settings->preferCompositingToLCDTextEnabled(); 817 return false; 818 } 819 820 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const 821 { 822 if (layer != m_renderView.layer()) 823 return false; 824 825 return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgroundIsEntirelyFixed(); 826 } 827 828 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const 829 { 830 // Get the fixed root background from the RenderView layer's compositedLayerMapping. 831 RenderLayer* viewLayer = m_renderView.layer(); 832 if (!viewLayer) 833 return 0; 834 835 if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground()) 836 return viewLayer->compositedLayerMapping()->backgroundLayer(); 837 838 return 0; 839 } 840 841 static void resetTrackedPaintInvalidationRectsRecursive(GraphicsLayer* graphicsLayer) 842 { 843 if (!graphicsLayer) 844 return; 845 846 graphicsLayer->resetTrackedPaintInvalidations(); 847 848 for (size_t i = 0; i < graphicsLayer->children().size(); ++i) 849 resetTrackedPaintInvalidationRectsRecursive(graphicsLayer->children()[i]); 850 851 if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer()) 852 resetTrackedPaintInvalidationRectsRecursive(replicaLayer); 853 854 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer()) 855 resetTrackedPaintInvalidationRectsRecursive(maskLayer); 856 857 if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLayer()) 858 resetTrackedPaintInvalidationRectsRecursive(clippingMaskLayer); 859 } 860 861 void RenderLayerCompositor::resetTrackedPaintInvalidationRects() 862 { 863 if (GraphicsLayer* rootLayer = rootGraphicsLayer()) 864 resetTrackedPaintInvalidationRectsRecursive(rootLayer); 865 } 866 867 void RenderLayerCompositor::setTracksPaintInvalidations(bool tracksPaintInvalidations) 868 { 869 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationClean); 870 m_isTrackingPaintInvalidations = tracksPaintInvalidations; 871 } 872 873 bool RenderLayerCompositor::isTrackingPaintInvalidations() const 874 { 875 return m_isTrackingPaintInvalidations; 876 } 877 878 static bool shouldCompositeOverflowControls(FrameView* view) 879 { 880 if (Page* page = view->frame().page()) { 881 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) 882 if (scrollingCoordinator->coordinatesScrollingForFrameView(view)) 883 return true; 884 } 885 886 return true; 887 } 888 889 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const 890 { 891 FrameView* view = m_renderView.frameView(); 892 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar(); 893 } 894 895 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const 896 { 897 FrameView* view = m_renderView.frameView(); 898 return shouldCompositeOverflowControls(view) && view->verticalScrollbar(); 899 } 900 901 bool RenderLayerCompositor::requiresScrollCornerLayer() const 902 { 903 FrameView* view = m_renderView.frameView(); 904 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible(); 905 } 906 907 void RenderLayerCompositor::updateOverflowControlsLayers() 908 { 909 #if USE(RUBBER_BANDING) 910 if (m_renderView.frame()->isLocalRoot()) { 911 if (!m_layerForOverhangShadow) { 912 m_layerForOverhangShadow = GraphicsLayer::create(graphicsLayerFactory(), this); 913 OverscrollTheme::theme()->setUpOverhangShadowLayer(m_layerForOverhangShadow.get()); 914 OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get()); 915 m_scrollLayer->addChild(m_layerForOverhangShadow.get()); 916 } 917 } else { 918 ASSERT(!m_layerForOverhangShadow); 919 } 920 #endif 921 GraphicsLayer* controlsParent = m_rootTransformLayer.get() ? m_rootTransformLayer.get() : m_overflowControlsHostLayer.get(); 922 923 if (requiresHorizontalScrollbarLayer()) { 924 if (!m_layerForHorizontalScrollbar) { 925 m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this); 926 } 927 928 if (m_layerForHorizontalScrollbar->parent() != controlsParent) { 929 controlsParent->addChild(m_layerForHorizontalScrollbar.get()); 930 931 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 932 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar); 933 } 934 } else if (m_layerForHorizontalScrollbar) { 935 m_layerForHorizontalScrollbar->removeFromParent(); 936 m_layerForHorizontalScrollbar = nullptr; 937 938 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 939 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar); 940 } 941 942 if (requiresVerticalScrollbarLayer()) { 943 if (!m_layerForVerticalScrollbar) { 944 m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this); 945 } 946 947 if (m_layerForVerticalScrollbar->parent() != controlsParent) { 948 controlsParent->addChild(m_layerForVerticalScrollbar.get()); 949 950 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 951 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar); 952 } 953 } else if (m_layerForVerticalScrollbar) { 954 m_layerForVerticalScrollbar->removeFromParent(); 955 m_layerForVerticalScrollbar = nullptr; 956 957 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 958 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar); 959 } 960 961 if (requiresScrollCornerLayer()) { 962 if (!m_layerForScrollCorner) { 963 m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this); 964 controlsParent->addChild(m_layerForScrollCorner.get()); 965 } 966 } else if (m_layerForScrollCorner) { 967 m_layerForScrollCorner->removeFromParent(); 968 m_layerForScrollCorner = nullptr; 969 } 970 971 m_renderView.frameView()->positionScrollbarLayers(); 972 } 973 974 void RenderLayerCompositor::ensureRootLayer() 975 { 976 RootLayerAttachment expectedAttachment = m_renderView.frame()->isLocalRoot() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; 977 if (expectedAttachment == m_rootLayerAttachment) 978 return; 979 980 if (!m_rootContentLayer) { 981 m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 982 IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect(); 983 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY())); 984 m_rootContentLayer->setPosition(FloatPoint()); 985 m_rootContentLayer->setOwnerNodeId(InspectorNodeIds::idForNode(m_renderView.generatingNode())); 986 987 // Need to clip to prevent transformed content showing outside this frame 988 m_rootContentLayer->setMasksToBounds(true); 989 } 990 991 if (!m_overflowControlsHostLayer) { 992 ASSERT(!m_scrollLayer); 993 ASSERT(!m_containerLayer); 994 995 // Create a layer to host the clipping layer and the overflow controls layers. 996 m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 997 998 // Clip iframe's overflow controls layer. 999 bool containerMasksToBounds = !m_renderView.frame()->isLocalRoot(); 1000 m_overflowControlsHostLayer->setMasksToBounds(containerMasksToBounds); 1001 1002 // Create a clipping layer if this is an iframe or settings require to clip. 1003 m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 1004 if (Settings* settings = m_renderView.document().settings()) { 1005 if (settings->mainFrameClipsContent()) 1006 containerMasksToBounds = true; 1007 } 1008 m_containerLayer->setMasksToBounds(containerMasksToBounds); 1009 1010 m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this); 1011 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 1012 scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true); 1013 1014 // Hook them up 1015 m_overflowControlsHostLayer->addChild(m_containerLayer.get()); 1016 m_containerLayer->addChild(m_scrollLayer.get()); 1017 m_scrollLayer->addChild(m_rootContentLayer.get()); 1018 1019 frameViewDidChangeSize(); 1020 } 1021 1022 // Check to see if we have to change the attachment 1023 if (m_rootLayerAttachment != RootLayerUnattached) 1024 detachRootLayer(); 1025 1026 attachRootLayer(expectedAttachment); 1027 } 1028 1029 void RenderLayerCompositor::destroyRootLayer() 1030 { 1031 if (!m_rootContentLayer) 1032 return; 1033 1034 detachRootLayer(); 1035 1036 #if USE(RUBBER_BANDING) 1037 if (m_layerForOverhangShadow) { 1038 m_layerForOverhangShadow->removeFromParent(); 1039 m_layerForOverhangShadow = nullptr; 1040 } 1041 #endif 1042 1043 if (m_layerForHorizontalScrollbar) { 1044 m_layerForHorizontalScrollbar->removeFromParent(); 1045 m_layerForHorizontalScrollbar = nullptr; 1046 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 1047 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar); 1048 if (Scrollbar* horizontalScrollbar = m_renderView.frameView()->verticalScrollbar()) 1049 m_renderView.frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size())); 1050 } 1051 1052 if (m_layerForVerticalScrollbar) { 1053 m_layerForVerticalScrollbar->removeFromParent(); 1054 m_layerForVerticalScrollbar = nullptr; 1055 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) 1056 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar); 1057 if (Scrollbar* verticalScrollbar = m_renderView.frameView()->verticalScrollbar()) 1058 m_renderView.frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size())); 1059 } 1060 1061 if (m_layerForScrollCorner) { 1062 m_layerForScrollCorner = nullptr; 1063 m_renderView.frameView()->invalidateScrollCorner(m_renderView.frameView()->scrollCornerRect()); 1064 } 1065 1066 if (m_overflowControlsHostLayer) { 1067 m_overflowControlsHostLayer = nullptr; 1068 m_containerLayer = nullptr; 1069 m_scrollLayer = nullptr; 1070 } 1071 ASSERT(!m_scrollLayer); 1072 m_rootContentLayer = nullptr; 1073 m_rootTransformLayer = nullptr; 1074 } 1075 1076 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment) 1077 { 1078 if (!m_rootContentLayer) 1079 return; 1080 1081 switch (attachment) { 1082 case RootLayerUnattached: 1083 ASSERT_NOT_REACHED(); 1084 break; 1085 case RootLayerAttachedViaChromeClient: { 1086 LocalFrame& frame = m_renderView.frameView()->frame(); 1087 Page* page = frame.page(); 1088 if (!page) 1089 return; 1090 page->chrome().client().attachRootGraphicsLayer(rootGraphicsLayer()); 1091 break; 1092 } 1093 case RootLayerAttachedViaEnclosingFrame: { 1094 HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement(); 1095 ASSERT(ownerElement); 1096 // The layer will get hooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration() 1097 // for the frame's renderer in the parent document. 1098 ownerElement->setNeedsCompositingUpdate(); 1099 break; 1100 } 1101 } 1102 1103 m_rootLayerAttachment = attachment; 1104 } 1105 1106 void RenderLayerCompositor::detachRootLayer() 1107 { 1108 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached) 1109 return; 1110 1111 switch (m_rootLayerAttachment) { 1112 case RootLayerAttachedViaEnclosingFrame: { 1113 // The layer will get unhooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration() 1114 // for the frame's renderer in the parent document. 1115 if (m_overflowControlsHostLayer) 1116 m_overflowControlsHostLayer->removeFromParent(); 1117 else 1118 m_rootContentLayer->removeFromParent(); 1119 1120 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) 1121 ownerElement->setNeedsCompositingUpdate(); 1122 break; 1123 } 1124 case RootLayerAttachedViaChromeClient: { 1125 LocalFrame& frame = m_renderView.frameView()->frame(); 1126 Page* page = frame.page(); 1127 if (!page) 1128 return; 1129 page->chrome().client().attachRootGraphicsLayer(0); 1130 } 1131 break; 1132 case RootLayerUnattached: 1133 break; 1134 } 1135 1136 m_rootLayerAttachment = RootLayerUnattached; 1137 } 1138 1139 void RenderLayerCompositor::updateRootLayerAttachment() 1140 { 1141 ensureRootLayer(); 1142 } 1143 1144 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const 1145 { 1146 if (Page* page = this->page()) 1147 return page->scrollingCoordinator(); 1148 1149 return 0; 1150 } 1151 1152 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const 1153 { 1154 if (Page* page = this->page()) 1155 return page->chrome().client().graphicsLayerFactory(); 1156 return 0; 1157 } 1158 1159 Page* RenderLayerCompositor::page() const 1160 { 1161 return m_renderView.frameView()->frame().page(); 1162 } 1163 1164 DocumentLifecycle& RenderLayerCompositor::lifecycle() const 1165 { 1166 return m_renderView.document().lifecycle(); 1167 } 1168 1169 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer) 1170 { 1171 String name; 1172 if (graphicsLayer == m_rootContentLayer.get()) { 1173 name = "Content Root Layer"; 1174 } else if (graphicsLayer == m_rootTransformLayer.get()) { 1175 name = "Root Transform Layer"; 1176 #if USE(RUBBER_BANDING) 1177 } else if (graphicsLayer == m_layerForOverhangShadow.get()) { 1178 name = "Overhang Areas Shadow"; 1179 #endif 1180 } else if (graphicsLayer == m_overflowControlsHostLayer.get()) { 1181 name = "Overflow Controls Host Layer"; 1182 } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) { 1183 name = "Horizontal Scrollbar Layer"; 1184 } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) { 1185 name = "Vertical Scrollbar Layer"; 1186 } else if (graphicsLayer == m_layerForScrollCorner.get()) { 1187 name = "Scroll Corner Layer"; 1188 } else if (graphicsLayer == m_containerLayer.get()) { 1189 name = "LocalFrame Clipping Layer"; 1190 } else if (graphicsLayer == m_scrollLayer.get()) { 1191 name = "LocalFrame Scrolling Layer"; 1192 } else { 1193 ASSERT_NOT_REACHED(); 1194 } 1195 1196 return name; 1197 } 1198 1199 } // namespace blink 1200