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
61namespace blink {
62
63RenderLayerCompositor::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
78RenderLayerCompositor::~RenderLayerCompositor()
79{
80    ASSERT(m_rootLayerAttachment == RootLayerUnattached);
81}
82
83bool 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
91bool RenderLayerCompositor::staleInCompositingMode() const
92{
93    return m_compositing;
94}
95
96void 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
121void 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
138bool RenderLayerCompositor::rootShouldAlwaysComposite() const
139{
140    if (!m_hasAcceleratedCompositing)
141        return false;
142    return m_renderView.frame()->isLocalRoot() || m_compositingReasonFinder.requiresCompositingForScrollableFrame();
143}
144
145void RenderLayerCompositor::updateAcceleratedCompositingSettings()
146{
147    m_compositingReasonFinder.updateTriggers();
148    m_hasAcceleratedCompositing = m_renderView.document().settings()->acceleratedCompositingEnabled();
149    m_rootShouldAlwaysCompositeDirty = true;
150}
151
152bool 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
161bool RenderLayerCompositor::preferCompositingToLCDTextEnabled() const
162{
163    return m_compositingReasonFinder.hasOverflowScrollTrigger();
164}
165
166static 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
187void 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
222void 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
230void 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
245void RenderLayerCompositor::assertNoUnresolvedDirtyBits()
246{
247    ASSERT(m_pendingUpdateType == CompositingUpdateNone);
248    ASSERT(!m_rootShouldAlwaysCompositeDirty);
249}
250
251#endif
252
253void 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
287void 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
299static 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
315void 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
403bool 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
485void 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
499void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
500{
501    if (m_overflowControlsHostLayer)
502        m_overflowControlsHostLayer->setPosition(contentsOffset);
503}
504
505void 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
517enum AcceleratedFixedRootBackgroundHistogramBuckets {
518    ScrolledMainFrameBucket = 0,
519    ScrolledMainFrameWithAcceleratedFixedRootBackground = 1,
520    ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2,
521    AcceleratedFixedRootBackgroundHistogramMax = 3
522};
523
524void 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
554void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange()
555{
556    if (m_containerLayer)
557        updateOverflowControlsLayers();
558}
559
560void 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
582bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer)
583{
584    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
585        return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea());
586    return false;
587}
588
589String 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
613RenderLayerCompositor* 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.
627bool 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
647static 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
658void 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
666RenderLayer* RenderLayerCompositor::rootRenderLayer() const
667{
668    return m_renderView.layer();
669}
670
671GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
672{
673    if (m_overflowControlsHostLayer)
674        return m_overflowControlsHostLayer.get();
675    return m_rootContentLayer.get();
676}
677
678GraphicsLayer* RenderLayerCompositor::scrollLayer() const
679{
680    return m_scrollLayer.get();
681}
682
683GraphicsLayer* RenderLayerCompositor::containerLayer() const
684{
685    return m_containerLayer.get();
686}
687
688GraphicsLayer* 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
702void 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
721void 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
739void RenderLayerCompositor::updatePotentialCompositingReasonsFromStyle(RenderLayer* layer)
740{
741    layer->setPotentialCompositingReasonsFromStyle(m_compositingReasonFinder.potentialCompositingReasonsFromStyle(layer->renderer()));
742}
743
744void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer)
745{
746    layer->setCompositingReasons(m_compositingReasonFinder.directReasons(layer), CompositingReasonComboAllDirectReasons);
747}
748
749void RenderLayerCompositor::setOverlayLayer(GraphicsLayer* layer)
750{
751    ASSERT(rootGraphicsLayer());
752
753    if (layer->parent() != m_overflowControlsHostLayer.get())
754        m_overflowControlsHostLayer->addChild(layer);
755}
756
757bool 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.
767bool 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.
775bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
776{
777    if (!layer->hasCompositingDescendant())
778        return false;
779    return layer->stackingNode()->hasNegativeZOrderList();
780}
781
782static 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
796void 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
813bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
814{
815    if (Settings* settings = m_renderView.document().settings())
816        return settings->preferCompositingToLCDTextEnabled();
817    return false;
818}
819
820bool 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
828GraphicsLayer* 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
841static 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
861void RenderLayerCompositor::resetTrackedPaintInvalidationRects()
862{
863    if (GraphicsLayer* rootLayer = rootGraphicsLayer())
864        resetTrackedPaintInvalidationRectsRecursive(rootLayer);
865}
866
867void RenderLayerCompositor::setTracksPaintInvalidations(bool tracksPaintInvalidations)
868{
869    ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationClean);
870    m_isTrackingPaintInvalidations = tracksPaintInvalidations;
871}
872
873bool RenderLayerCompositor::isTrackingPaintInvalidations() const
874{
875    return m_isTrackingPaintInvalidations;
876}
877
878static 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
889bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
890{
891    FrameView* view = m_renderView.frameView();
892    return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
893}
894
895bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
896{
897    FrameView* view = m_renderView.frameView();
898    return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
899}
900
901bool RenderLayerCompositor::requiresScrollCornerLayer() const
902{
903    FrameView* view = m_renderView.frameView();
904    return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
905}
906
907void 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
974void 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
1029void 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
1076void 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
1106void 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
1139void RenderLayerCompositor::updateRootLayerAttachment()
1140{
1141    ensureRootLayer();
1142}
1143
1144ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
1145{
1146    if (Page* page = this->page())
1147        return page->scrollingCoordinator();
1148
1149    return 0;
1150}
1151
1152GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
1153{
1154    if (Page* page = this->page())
1155        return page->chrome().client().graphicsLayerFactory();
1156    return 0;
1157}
1158
1159Page* RenderLayerCompositor::page() const
1160{
1161    return m_renderView.frameView()->frame().page();
1162}
1163
1164DocumentLifecycle& RenderLayerCompositor::lifecycle() const
1165{
1166    return m_renderView.document().lifecycle();
1167}
1168
1169String 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