Home | History | Annotate | Download | only in compositing
      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