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 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 "RenderLayerCompositor.h"
29
30#include "AnimationController.h"
31#include "CanvasRenderingContext.h"
32#include "CSSPropertyNames.h"
33#include "Chrome.h"
34#include "ChromeClient.h"
35#include "FlowThreadController.h"
36#include "Frame.h"
37#include "FrameView.h"
38#include "GraphicsLayer.h"
39#include "HTMLCanvasElement.h"
40#include "HTMLIFrameElement.h"
41#include "HTMLNames.h"
42#include "HitTestResult.h"
43#include "InspectorInstrumentation.h"
44#include "Logging.h"
45#include "MainFrame.h"
46#include "NodeList.h"
47#include "Page.h"
48#include "RenderEmbeddedObject.h"
49#include "RenderFlowThread.h"
50#include "RenderFullScreen.h"
51#include "RenderGeometryMap.h"
52#include "RenderIFrame.h"
53#include "RenderLayerBacking.h"
54#include "RenderNamedFlowFragment.h"
55#include "RenderReplica.h"
56#include "RenderVideo.h"
57#include "RenderView.h"
58#include "ScrollingConstraints.h"
59#include "ScrollingCoordinator.h"
60#include "Settings.h"
61#include "TiledBacking.h"
62#include "TransformState.h"
63#include <wtf/CurrentTime.h>
64#include <wtf/TemporaryChange.h>
65#include <wtf/text/CString.h>
66#include <wtf/text/StringBuilder.h>
67
68#if PLATFORM(IOS)
69#include "LegacyTileCache.h"
70#include "MainFrame.h"
71#include "Region.h"
72#include "RenderScrollbar.h"
73#endif
74
75#ifndef NDEBUG
76#include "RenderTreeAsText.h"
77#endif
78
79#if ENABLE(3D_RENDERING)
80// This symbol is used to determine from a script whether 3D rendering is enabled (via 'nm').
81bool WebCoreHas3DRendering = true;
82#endif
83
84#if !PLATFORM(MAC) && !PLATFORM(IOS)
85#define WTF_USE_COMPOSITING_FOR_SMALL_CANVASES 1
86#endif
87
88namespace WebCore {
89
90static const int canvasAreaThresholdRequiringCompositing = 50 * 100;
91// During page loading delay layer flushes up to this many seconds to allow them coalesce, reducing workload.
92#if PLATFORM(IOS)
93static const double throttledLayerFlushInitialDelay = .5;
94static const double throttledLayerFlushDelay = 1.5;
95#else
96static const double throttledLayerFlushInitialDelay = .5;
97static const double throttledLayerFlushDelay = .5;
98#endif
99
100using namespace HTMLNames;
101
102class OverlapMapContainer {
103public:
104    void add(const IntRect& bounds)
105    {
106        m_layerRects.append(bounds);
107        m_boundingBox.unite(bounds);
108    }
109
110    bool overlapsLayers(const IntRect& bounds) const
111    {
112        // Checking with the bounding box will quickly reject cases when
113        // layers are created for lists of items going in one direction and
114        // never overlap with each other.
115        if (!bounds.intersects(m_boundingBox))
116            return false;
117        for (unsigned i = 0; i < m_layerRects.size(); i++) {
118            if (m_layerRects[i].intersects(bounds))
119                return true;
120        }
121        return false;
122    }
123
124    void unite(const OverlapMapContainer& otherContainer)
125    {
126        m_layerRects.appendVector(otherContainer.m_layerRects);
127        m_boundingBox.unite(otherContainer.m_boundingBox);
128    }
129private:
130    Vector<IntRect> m_layerRects;
131    IntRect m_boundingBox;
132};
133
134class RenderLayerCompositor::OverlapMap {
135    WTF_MAKE_NONCOPYABLE(OverlapMap);
136public:
137    OverlapMap()
138        : m_geometryMap(UseTransforms)
139    {
140        // Begin assuming the root layer will be composited so that there is
141        // something on the stack. The root layer should also never get an
142        // popCompositingContainer call.
143        pushCompositingContainer();
144    }
145
146    void add(const RenderLayer* layer, const IntRect& bounds)
147    {
148        // Layers do not contribute to overlap immediately--instead, they will
149        // contribute to overlap as soon as their composited ancestor has been
150        // recursively processed and popped off the stack.
151        ASSERT(m_overlapStack.size() >= 2);
152        m_overlapStack[m_overlapStack.size() - 2].add(bounds);
153        m_layers.add(layer);
154    }
155
156    bool contains(const RenderLayer* layer)
157    {
158        return m_layers.contains(layer);
159    }
160
161    bool overlapsLayers(const IntRect& bounds) const
162    {
163        return m_overlapStack.last().overlapsLayers(bounds);
164    }
165
166    bool isEmpty()
167    {
168        return m_layers.isEmpty();
169    }
170
171    void pushCompositingContainer()
172    {
173        m_overlapStack.append(OverlapMapContainer());
174    }
175
176    void popCompositingContainer()
177    {
178        m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last());
179        m_overlapStack.removeLast();
180    }
181
182    RenderGeometryMap& geometryMap() { return m_geometryMap; }
183
184private:
185    struct RectList {
186        Vector<IntRect> rects;
187        IntRect boundingRect;
188
189        void append(const IntRect& rect)
190        {
191            rects.append(rect);
192            boundingRect.unite(rect);
193        }
194
195        void append(const RectList& rectList)
196        {
197            rects.appendVector(rectList.rects);
198            boundingRect.unite(rectList.boundingRect);
199        }
200
201        bool intersects(const IntRect& rect) const
202        {
203            if (!rects.size() || !boundingRect.intersects(rect))
204                return false;
205
206            for (unsigned i = 0; i < rects.size(); i++) {
207                if (rects[i].intersects(rect))
208                    return true;
209            }
210            return false;
211        }
212    };
213
214    Vector<OverlapMapContainer> m_overlapStack;
215    HashSet<const RenderLayer*> m_layers;
216    RenderGeometryMap m_geometryMap;
217};
218
219struct CompositingState {
220    CompositingState(RenderLayer* compAncestor, bool testOverlap = true)
221        : m_compositingAncestor(compAncestor)
222        , m_subtreeIsCompositing(false)
223        , m_testingOverlap(testOverlap)
224#if ENABLE(CSS_COMPOSITING)
225        , m_hasNotIsolatedCompositedBlendingDescendants(false)
226#endif
227#ifndef NDEBUG
228        , m_depth(0)
229#endif
230    {
231    }
232
233    CompositingState(const CompositingState& other)
234        : m_compositingAncestor(other.m_compositingAncestor)
235        , m_subtreeIsCompositing(other.m_subtreeIsCompositing)
236        , m_testingOverlap(other.m_testingOverlap)
237#if ENABLE(CSS_COMPOSITING)
238        , m_hasNotIsolatedCompositedBlendingDescendants(other.m_hasNotIsolatedCompositedBlendingDescendants)
239#endif
240#ifndef NDEBUG
241        , m_depth(other.m_depth + 1)
242#endif
243    {
244    }
245
246    RenderLayer* m_compositingAncestor;
247    bool m_subtreeIsCompositing;
248    bool m_testingOverlap;
249#if ENABLE(CSS_COMPOSITING)
250    bool m_hasNotIsolatedCompositedBlendingDescendants;
251#endif
252#ifndef NDEBUG
253    int m_depth;
254#endif
255};
256
257
258#if !LOG_DISABLED
259static inline bool compositingLogEnabled()
260{
261    return LogCompositing.state == WTFLogChannelOn;
262}
263#endif
264
265RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView)
266    : m_renderView(renderView)
267    , m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
268    , m_hasAcceleratedCompositing(true)
269    , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
270    , m_compositedLayerCount(0)
271    , m_showDebugBorders(false)
272    , m_showRepaintCounter(false)
273    , m_acceleratedDrawingEnabled(false)
274    , m_reevaluateCompositingAfterLayout(false)
275    , m_compositing(false)
276    , m_compositingLayersNeedRebuild(false)
277    , m_flushingLayers(false)
278    , m_shouldFlushOnReattach(false)
279    , m_forceCompositingMode(false)
280    , m_inPostLayoutUpdate(false)
281    , m_subframeScrollLayersNeedReattach(false)
282    , m_isTrackingRepaints(false)
283    , m_layersWithTiledBackingCount(0)
284    , m_rootLayerAttachment(RootLayerUnattached)
285    , m_layerFlushTimer(this, &RenderLayerCompositor::layerFlushTimerFired)
286    , m_layerFlushThrottlingEnabled(false)
287    , m_layerFlushThrottlingTemporarilyDisabledForInteraction(false)
288    , m_hasPendingLayerFlush(false)
289    , m_paintRelatedMilestonesTimer(this, &RenderLayerCompositor::paintRelatedMilestonesTimerFired)
290#if !LOG_DISABLED
291    , m_rootLayerUpdateCount(0)
292    , m_obligateCompositedLayerCount(0)
293    , m_secondaryCompositedLayerCount(0)
294    , m_obligatoryBackingStoreBytes(0)
295    , m_secondaryBackingStoreBytes(0)
296#endif
297{
298}
299
300RenderLayerCompositor::~RenderLayerCompositor()
301{
302    // Take care that the owned GraphicsLayers are deleted first as their destructors may call back here.
303    m_clipLayer = nullptr;
304    m_scrollLayer = nullptr;
305    ASSERT(m_rootLayerAttachment == RootLayerUnattached);
306}
307
308void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
309{
310    if (enable != m_compositing) {
311        m_compositing = enable;
312
313        if (m_compositing) {
314            ensureRootLayer();
315            notifyIFramesOfCompositingChange();
316        } else
317            destroyRootLayer();
318    }
319}
320
321void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
322{
323    bool hasAcceleratedCompositing = false;
324    bool showDebugBorders = false;
325    bool showRepaintCounter = false;
326    bool forceCompositingMode = false;
327    bool acceleratedDrawingEnabled = false;
328
329    const Settings& settings = m_renderView.frameView().frame().settings();
330    hasAcceleratedCompositing = settings.acceleratedCompositingEnabled();
331
332    // We allow the chrome to override the settings, in case the page is rendered
333    // on a chrome that doesn't allow accelerated compositing.
334    if (hasAcceleratedCompositing) {
335        if (Page* page = this->page()) {
336            m_compositingTriggers = page->chrome().client().allowedCompositingTriggers();
337            hasAcceleratedCompositing = m_compositingTriggers;
338        }
339    }
340
341    showDebugBorders = settings.showDebugBorders();
342    showRepaintCounter = settings.showRepaintCounter();
343    forceCompositingMode = settings.forceCompositingMode() && hasAcceleratedCompositing;
344
345    if (forceCompositingMode && m_renderView.document().ownerElement())
346        forceCompositingMode = requiresCompositingForScrollableFrame();
347
348    acceleratedDrawingEnabled = settings.acceleratedDrawingEnabled();
349
350    if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode)
351        setCompositingLayersNeedRebuild();
352
353    bool debugBordersChanged = m_showDebugBorders != showDebugBorders;
354    m_hasAcceleratedCompositing = hasAcceleratedCompositing;
355    m_showDebugBorders = showDebugBorders;
356    m_showRepaintCounter = showRepaintCounter;
357    m_forceCompositingMode = forceCompositingMode;
358    m_acceleratedDrawingEnabled = acceleratedDrawingEnabled;
359
360    if (debugBordersChanged) {
361        if (m_layerForHorizontalScrollbar)
362            m_layerForHorizontalScrollbar->setShowDebugBorder(m_showDebugBorders);
363
364        if (m_layerForVerticalScrollbar)
365            m_layerForVerticalScrollbar->setShowDebugBorder(m_showDebugBorders);
366
367        if (m_layerForScrollCorner)
368            m_layerForScrollCorner->setShowDebugBorder(m_showDebugBorders);
369    }
370}
371
372bool RenderLayerCompositor::canRender3DTransforms() const
373{
374    return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
375}
376
377void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
378{
379    if (inCompositingMode())
380        m_compositingLayersNeedRebuild = needRebuild;
381}
382
383void RenderLayerCompositor::customPositionForVisibleRectComputation(const GraphicsLayer* graphicsLayer, FloatPoint& position) const
384{
385    if (graphicsLayer != m_scrollLayer.get())
386        return;
387
388    FloatPoint scrollPosition = -position;
389
390    if (m_renderView.frameView().scrollBehaviorForFixedElements() == StickToDocumentBounds)
391        scrollPosition = m_renderView.frameView().constrainScrollPositionForOverhang(roundedIntPoint(scrollPosition));
392
393    position = -scrollPosition;
394}
395
396void RenderLayerCompositor::notifyFlushRequired(const GraphicsLayer* layer)
397{
398    scheduleLayerFlush(layer->canThrottleLayerFlush());
399}
400
401void RenderLayerCompositor::scheduleLayerFlushNow()
402{
403    m_hasPendingLayerFlush = false;
404    if (Page* page = this->page())
405        page->chrome().client().scheduleCompositingLayerFlush();
406}
407
408void RenderLayerCompositor::scheduleLayerFlush(bool canThrottle)
409{
410    ASSERT(!m_flushingLayers);
411
412    if (canThrottle)
413        startInitialLayerFlushTimerIfNeeded();
414
415    if (canThrottle && isThrottlingLayerFlushes()) {
416        m_hasPendingLayerFlush = true;
417        return;
418    }
419    scheduleLayerFlushNow();
420}
421
422#if PLATFORM(IOS)
423ChromeClient* RenderLayerCompositor::chromeClient() const
424{
425    Page* page = m_renderView.frameView().frame().page();
426    if (!page)
427        return 0;
428    return &page->chrome().client();
429}
430#endif
431
432void RenderLayerCompositor::flushPendingLayerChanges(bool isFlushRoot)
433{
434    // FrameView::flushCompositingStateIncludingSubframes() flushes each subframe,
435    // but GraphicsLayer::flushCompositingState() will cross frame boundaries
436    // if the GraphicsLayers are connected (the RootLayerAttachedViaEnclosingFrame case).
437    // As long as we're not the root of the flush, we can bail.
438    if (!isFlushRoot && rootLayerAttachment() == RootLayerAttachedViaEnclosingFrame)
439        return;
440
441    if (rootLayerAttachment() == RootLayerUnattached) {
442#if PLATFORM(IOS)
443        startLayerFlushTimerIfNeeded();
444#endif
445        m_shouldFlushOnReattach = true;
446        return;
447    }
448
449    FrameView& frameView = m_renderView.frameView();
450    AnimationUpdateBlock animationUpdateBlock(&frameView.frame().animation());
451
452    ASSERT(!m_flushingLayers);
453    m_flushingLayers = true;
454
455    if (GraphicsLayer* rootLayer = rootGraphicsLayer()) {
456#if PLATFORM(IOS)
457        double horizontalMargin = defaultTileWidth / pageScaleFactor();
458        double verticalMargin = defaultTileHeight / pageScaleFactor();
459        FloatRect visibleRect = frameView.computeCoverageRect(horizontalMargin, verticalMargin);
460        rootLayer->flushCompositingState(visibleRect);
461#else
462        // Having a m_clipLayer indicates that we're doing scrolling via GraphicsLayers.
463        IntRect visibleRect = m_clipLayer ? IntRect(IntPoint(), frameView.unscaledVisibleContentSizeIncludingObscuredArea()) : frameView.visibleContentRect();
464        if (!frameView.exposedRect().isInfinite())
465            visibleRect.intersect(IntRect(frameView.exposedRect()));
466        rootLayer->flushCompositingState(visibleRect);
467#endif
468    }
469
470    ASSERT(m_flushingLayers);
471    m_flushingLayers = false;
472
473    updateScrollCoordinatedLayersAfterFlushIncludingSubframes();
474
475#if PLATFORM(IOS)
476    ChromeClient* client = this->chromeClient();
477    if (client && isFlushRoot)
478        client->didFlushCompositingLayers();
479#endif
480
481    startLayerFlushTimerIfNeeded();
482}
483
484void RenderLayerCompositor::updateScrollCoordinatedLayersAfterFlushIncludingSubframes()
485{
486    updateScrollCoordinatedLayersAfterFlush();
487
488    Frame& frame = m_renderView.frameView().frame();
489    for (Frame* subframe = frame.tree().firstChild(); subframe; subframe = subframe->tree().traverseNext(&frame)) {
490        RenderView* view = subframe->contentRenderer();
491        if (!view)
492            continue;
493
494        view->compositor().updateScrollCoordinatedLayersAfterFlush();
495    }
496}
497
498void RenderLayerCompositor::updateScrollCoordinatedLayersAfterFlush()
499{
500#if PLATFORM(IOS)
501    updateCustomLayersAfterFlush();
502#endif
503
504    for (auto it = m_scrollCoordinatedLayersNeedingUpdate.begin(), end = m_scrollCoordinatedLayersNeedingUpdate.end(); it != end; ++it)
505        updateScrollCoordinatedStatus(**it);
506
507    m_scrollCoordinatedLayersNeedingUpdate.clear();
508}
509
510#if PLATFORM(IOS)
511static bool scrollbarHasDisplayNone(Scrollbar* scrollbar)
512{
513    if (!scrollbar || !scrollbar->isCustomScrollbar())
514        return false;
515
516    RefPtr<RenderStyle> scrollbarStyle = static_cast<RenderScrollbar*>(scrollbar)->getScrollbarPseudoStyle(ScrollbarBGPart, SCROLLBAR);
517    return scrollbarStyle && scrollbarStyle->display() == NONE;
518}
519
520// FIXME: Can we make |layer| const RenderLayer&?
521static void updateScrollingLayerWithClient(RenderLayer& layer, ChromeClient* client)
522{
523    if (!client)
524        return;
525
526    RenderLayerBacking* backing = layer.backing();
527    ASSERT(backing);
528
529    bool allowHorizontalScrollbar = !scrollbarHasDisplayNone(layer.horizontalScrollbar());
530    bool allowVerticalScrollbar = !scrollbarHasDisplayNone(layer.verticalScrollbar());
531    client->addOrUpdateScrollingLayer(layer.renderer().element(), backing->scrollingLayer()->platformLayer(), backing->scrollingContentsLayer()->platformLayer(),
532        layer.scrollableContentsSize(), allowHorizontalScrollbar, allowVerticalScrollbar);
533}
534
535void RenderLayerCompositor::updateCustomLayersAfterFlush()
536{
537    registerAllViewportConstrainedLayers();
538
539    if (!m_scrollingLayersNeedingUpdate.isEmpty()) {
540        ChromeClient* chromeClient = this->chromeClient();
541
542        for (auto it = m_scrollingLayersNeedingUpdate.begin(), end = m_scrollingLayersNeedingUpdate.end(); it != end; ++it)
543            updateScrollingLayerWithClient(**it, chromeClient);
544        m_scrollingLayersNeedingUpdate.clear();
545    }
546    m_scrollingLayersNeedingUpdate.clear();
547}
548#endif
549
550void RenderLayerCompositor::didFlushChangesForLayer(RenderLayer& layer, const GraphicsLayer* graphicsLayer)
551{
552    if (m_scrollCoordinatedLayers.contains(&layer))
553        m_scrollCoordinatedLayersNeedingUpdate.add(&layer);
554
555#if PLATFORM(IOS)
556    if (m_scrollingLayers.contains(&layer))
557        m_scrollingLayersNeedingUpdate.add(&layer);
558#endif
559
560    RenderLayerBacking* backing = layer.backing();
561    if (backing->backgroundLayerPaintsFixedRootBackground() && graphicsLayer == backing->backgroundLayer())
562        fixedRootBackgroundLayerChanged();
563}
564
565void RenderLayerCompositor::didPaintBacking(RenderLayerBacking*)
566{
567    FrameView& frameView = m_renderView.frameView();
568    frameView.setLastPaintTime(monotonicallyIncreasingTime());
569    if (frameView.milestonesPendingPaint() && !m_paintRelatedMilestonesTimer.isActive())
570        m_paintRelatedMilestonesTimer.startOneShot(0);
571}
572
573void RenderLayerCompositor::didChangeVisibleRect()
574{
575    GraphicsLayer* rootLayer = rootGraphicsLayer();
576    if (!rootLayer)
577        return;
578
579    const FrameView& frameView = m_renderView.frameView();
580
581#if PLATFORM(IOS)
582    IntRect visibleRect = enclosingIntRect(frameView.exposedContentRect());
583#else
584    IntRect visibleRect = m_clipLayer ? IntRect(IntPoint(), frameView.contentsSize()) : frameView.visibleContentRect();
585#endif
586    if (!rootLayer->visibleRectChangeRequiresFlush(visibleRect))
587        return;
588    scheduleLayerFlushNow();
589}
590
591void RenderLayerCompositor::notifyFlushBeforeDisplayRefresh(const GraphicsLayer*)
592{
593    if (!m_layerUpdater) {
594        PlatformDisplayID displayID = 0;
595        if (Page* page = this->page())
596            displayID = page->chrome().displayID();
597
598        m_layerUpdater = std::make_unique<GraphicsLayerUpdater>(this, displayID);
599    }
600
601    m_layerUpdater->scheduleUpdate();
602}
603
604void RenderLayerCompositor::flushLayersSoon(GraphicsLayerUpdater*)
605{
606    scheduleLayerFlush(true);
607}
608
609void RenderLayerCompositor::layerTiledBackingUsageChanged(const GraphicsLayer* graphicsLayer, bool usingTiledBacking)
610{
611    if (usingTiledBacking) {
612        ++m_layersWithTiledBackingCount;
613
614        if (Page* page = this->page())
615            graphicsLayer->tiledBacking()->setIsInWindow(page->isInWindow());
616    } else {
617        ASSERT(m_layersWithTiledBackingCount > 0);
618        --m_layersWithTiledBackingCount;
619    }
620}
621
622RenderLayerCompositor* RenderLayerCompositor::enclosingCompositorFlushingLayers() const
623{
624    for (Frame* frame = &m_renderView.frameView().frame(); frame; frame = frame->tree().parent()) {
625        RenderLayerCompositor* compositor = frame->contentRenderer() ? &frame->contentRenderer()->compositor() : nullptr;
626        if (compositor->isFlushingLayers())
627            return compositor;
628    }
629
630    return 0;
631}
632
633void RenderLayerCompositor::scheduleCompositingLayerUpdate()
634{
635    if (!m_updateCompositingLayersTimer.isActive())
636        m_updateCompositingLayersTimer.startOneShot(0);
637}
638
639void RenderLayerCompositor::updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>&)
640{
641    updateCompositingLayers(CompositingUpdateAfterLayout);
642}
643
644bool RenderLayerCompositor::hasAnyAdditionalCompositedLayers(const RenderLayer& rootLayer) const
645{
646    return m_compositedLayerCount > (rootLayer.isComposited() ? 1 : 0);
647}
648
649void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
650{
651    m_updateCompositingLayersTimer.stop();
652
653    ASSERT(!m_renderView.document().inPageCache());
654
655    // Compositing layers will be updated in Document::implicitClose() if suppressed here.
656    if (!m_renderView.document().visualUpdatesAllowed())
657        return;
658
659    // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished.
660    if (m_renderView.needsLayout())
661        return;
662
663    if (m_forceCompositingMode && !m_compositing)
664        enableCompositingMode(true);
665
666    if (!m_reevaluateCompositingAfterLayout && !m_compositing)
667        return;
668
669    AnimationUpdateBlock animationUpdateBlock(&m_renderView.frameView().frame().animation());
670
671    TemporaryChange<bool> postLayoutChange(m_inPostLayoutUpdate, true);
672
673    bool checkForHierarchyUpdate = m_reevaluateCompositingAfterLayout;
674    bool needGeometryUpdate = false;
675
676    switch (updateType) {
677    case CompositingUpdateAfterStyleChange:
678    case CompositingUpdateAfterLayout:
679    case CompositingUpdateOnHitTest:
680        checkForHierarchyUpdate = true;
681        break;
682    case CompositingUpdateOnScroll:
683        checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
684
685        needGeometryUpdate = true;
686        break;
687    case CompositingUpdateOnCompositedScroll:
688        needGeometryUpdate = true;
689        break;
690    }
691
692    if (!checkForHierarchyUpdate && !needGeometryUpdate)
693        return;
694
695    bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
696    bool isFullUpdate = !updateRoot;
697
698    // Only clear the flag if we're updating the entire hierarchy.
699    m_compositingLayersNeedRebuild = false;
700    updateRoot = &rootRenderLayer();
701
702    if (isFullUpdate && updateType == CompositingUpdateAfterLayout)
703        m_reevaluateCompositingAfterLayout = false;
704
705#if !LOG_DISABLED
706    double startTime = 0;
707    if (compositingLogEnabled()) {
708        ++m_rootLayerUpdateCount;
709        startTime = monotonicallyIncreasingTime();
710    }
711#endif
712
713    if (checkForHierarchyUpdate) {
714        if (m_renderView.hasRenderNamedFlowThreads() && isFullUpdate)
715            m_renderView.flowThreadController().updateFlowThreadsLayerToRegionMappingsIfNeeded();
716        // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
717        // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
718        CompositingState compState(updateRoot);
719        bool layersChanged = false;
720        bool saw3DTransform = false;
721        OverlapMap overlapTestRequestMap;
722        computeCompositingRequirements(nullptr, *updateRoot, &overlapTestRequestMap, compState, layersChanged, saw3DTransform);
723        needHierarchyUpdate |= layersChanged;
724    }
725
726#if !LOG_DISABLED
727    if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
728        m_obligateCompositedLayerCount = 0;
729        m_secondaryCompositedLayerCount = 0;
730        m_obligatoryBackingStoreBytes = 0;
731        m_secondaryBackingStoreBytes = 0;
732
733        Frame& frame = m_renderView.frameView().frame();
734        bool isMainFrame = !m_renderView.document().ownerElement();
735        LOG(Compositing, "\nUpdate %d of %s.\n", m_rootLayerUpdateCount, isMainFrame ? "main frame" : frame.tree().uniqueName().string().utf8().data());
736    }
737#endif
738
739    if (needHierarchyUpdate) {
740        // Update the hierarchy of the compositing layers.
741        Vector<GraphicsLayer*> childList;
742        rebuildCompositingLayerTree(*updateRoot, childList, 0);
743
744        // Host the document layer in the RenderView's root layer.
745        if (isFullUpdate) {
746            appendOverlayLayers(childList);
747            // Even when childList is empty, don't drop out of compositing mode if there are
748            // composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
749            if (childList.isEmpty() && !hasAnyAdditionalCompositedLayers(*updateRoot))
750                destroyRootLayer();
751            else if (m_rootContentLayer)
752                m_rootContentLayer->setChildren(childList);
753        }
754
755        reattachSubframeScrollLayers();
756    } else if (needGeometryUpdate) {
757        // We just need to do a geometry update. This is only used for position:fixed scrolling;
758        // most of the time, geometry is updated via RenderLayer::styleChanged().
759        updateLayerTreeGeometry(*updateRoot, 0);
760        ASSERT(!isFullUpdate || !m_subframeScrollLayersNeedReattach);
761    }
762
763#if !LOG_DISABLED
764    if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
765        double endTime = monotonicallyIncreasingTime();
766        LOG(Compositing, "Total layers   primary   secondary   obligatory backing (KB)   secondary backing(KB)   total backing (KB)  update time (ms)\n");
767
768        LOG(Compositing, "%8d %11d %9d %20.2f %22.2f %22.2f %18.2f\n",
769            m_obligateCompositedLayerCount + m_secondaryCompositedLayerCount, m_obligateCompositedLayerCount,
770            m_secondaryCompositedLayerCount, m_obligatoryBackingStoreBytes / 1024, m_secondaryBackingStoreBytes / 1024, (m_obligatoryBackingStoreBytes + m_secondaryBackingStoreBytes) / 1024, 1000.0 * (endTime - startTime));
771    }
772#endif
773    ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
774
775    if (!hasAcceleratedCompositing())
776        enableCompositingMode(false);
777
778    // Inform the inspector that the layer tree has changed.
779    InspectorInstrumentation::layerTreeDidChange(page());
780}
781
782void RenderLayerCompositor::appendOverlayLayers(Vector<GraphicsLayer*>& childList)
783{
784    Frame& frame = m_renderView.frameView().frame();
785    Page* page = frame.page();
786    if (!page)
787        return;
788
789    if (GraphicsLayer* overlayLayer = page->chrome().client().documentOverlayLayerForFrame(frame))
790        childList.append(overlayLayer);
791}
792
793void RenderLayerCompositor::layerBecameNonComposited(const RenderLayer& layer)
794{
795    // Inform the inspector that the given RenderLayer was destroyed.
796    InspectorInstrumentation::renderLayerDestroyed(page(), &layer);
797
798    ASSERT(m_compositedLayerCount > 0);
799    --m_compositedLayerCount;
800}
801
802#if !LOG_DISABLED
803void RenderLayerCompositor::logLayerInfo(const RenderLayer& layer, int depth)
804{
805    if (!compositingLogEnabled())
806        return;
807
808    RenderLayerBacking* backing = layer.backing();
809    if (requiresCompositingLayer(layer) || layer.isRootLayer()) {
810        ++m_obligateCompositedLayerCount;
811        m_obligatoryBackingStoreBytes += backing->backingStoreMemoryEstimate();
812    } else {
813        ++m_secondaryCompositedLayerCount;
814        m_secondaryBackingStoreBytes += backing->backingStoreMemoryEstimate();
815    }
816
817    StringBuilder logString;
818    logString.append(String::format("%*p %dx%d %.2fKB", 12 + depth * 2, &layer,
819        backing->compositedBounds().width().round(), backing->compositedBounds().height().round(),
820        backing->backingStoreMemoryEstimate() / 1024));
821
822    logString.append(" (");
823    logString.append(logReasonsForCompositing(layer));
824    logString.append(") ");
825
826    if (backing->graphicsLayer()->contentsOpaque() || backing->paintsIntoCompositedAncestor()) {
827        logString.append('[');
828        if (backing->graphicsLayer()->contentsOpaque())
829            logString.append("opaque");
830        if (backing->paintsIntoCompositedAncestor())
831            logString.append("paints into ancestor");
832        logString.append("] ");
833    }
834
835    logString.append(layer.name());
836
837    LOG(Compositing, "%s", logString.toString().utf8().data());
838}
839#endif
840
841bool RenderLayerCompositor::updateBacking(RenderLayer& layer, CompositingChangeRepaint shouldRepaint)
842{
843    bool layerChanged = false;
844    RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason;
845
846    if (needsToBeComposited(layer, &viewportConstrainedNotCompositedReason)) {
847        enableCompositingMode();
848
849        if (!layer.backing()) {
850            // If we need to repaint, do so before making backing
851            if (shouldRepaint == CompositingChangeRepaintNow)
852                repaintOnCompositingChange(layer);
853
854            layer.ensureBacking();
855
856            // At this time, the ScrollingCoordinator only supports the top-level frame.
857            if (layer.isRootLayer() && !m_renderView.document().ownerElement()) {
858                updateScrollCoordinatedStatus(layer);
859                if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
860                    scrollingCoordinator->frameViewRootLayerDidChange(&m_renderView.frameView());
861#if ENABLE(RUBBER_BANDING)
862                if (Page* page = this->page()) {
863                    updateLayerForHeader(page->headerHeight());
864                    updateLayerForFooter(page->footerHeight());
865                }
866#endif
867                if (m_renderView.frameView().frame().settings().backgroundShouldExtendBeyondPage())
868                    m_rootContentLayer->setMasksToBounds(false);
869
870                if (TiledBacking* tiledBacking = layer.backing()->tiledBacking())
871                    tiledBacking->setTopContentInset(m_renderView.frameView().topContentInset());
872            }
873
874            // This layer and all of its descendants have cached repaints rects that are relative to
875            // the repaint container, so change when compositing changes; we need to update them here.
876            if (layer.parent())
877                layer.computeRepaintRectsIncludingDescendants();
878
879            layerChanged = true;
880        }
881    } else {
882        if (layer.backing()) {
883            // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to
884            // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
885            // are both either composited, or not composited.
886            if (layer.isReflection()) {
887                RenderLayer* sourceLayer = toRenderLayerModelObject(layer.renderer().parent())->layer();
888                if (RenderLayerBacking* backing = sourceLayer->backing()) {
889                    ASSERT(backing->graphicsLayer()->replicaLayer() == layer.backing()->graphicsLayer());
890                    backing->graphicsLayer()->setReplicatedByLayer(0);
891                }
892            }
893
894            removeFromScrollCoordinatedLayers(layer);
895
896            layer.clearBacking();
897            layerChanged = true;
898
899            // This layer and all of its descendants have cached repaints rects that are relative to
900            // the repaint container, so change when compositing changes; we need to update them here.
901            layer.computeRepaintRectsIncludingDescendants();
902
903            // If we need to repaint, do so now that we've removed the backing
904            if (shouldRepaint == CompositingChangeRepaintNow)
905                repaintOnCompositingChange(layer);
906        }
907    }
908
909#if ENABLE(VIDEO)
910    if (layerChanged && layer.renderer().isVideo()) {
911        // If it's a video, give the media player a chance to hook up to the layer.
912        toRenderVideo(layer.renderer()).acceleratedRenderingStateChanged();
913    }
914#endif
915
916    if (layerChanged && layer.renderer().isWidget()) {
917        RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderWidget(&layer.renderer()));
918        if (innerCompositor && innerCompositor->inCompositingMode())
919            innerCompositor->updateRootLayerAttachment();
920    }
921
922    if (layerChanged)
923        layer.clearClipRectsIncludingDescendants(PaintingClipRects);
924
925    // If a fixed position layer gained/lost a backing or the reason not compositing it changed,
926    // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
927    if (layer.renderer().style().position() == FixedPosition) {
928        if (layer.viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) {
929            layer.setViewportConstrainedNotCompositedReason(viewportConstrainedNotCompositedReason);
930            layerChanged = true;
931        }
932        if (layerChanged) {
933            if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
934                scrollingCoordinator->frameViewFixedObjectsDidChange(&m_renderView.frameView());
935        }
936    } else
937        layer.setViewportConstrainedNotCompositedReason(RenderLayer::NoNotCompositedReason);
938
939    if (layer.backing())
940        layer.backing()->updateDebugIndicators(m_showDebugBorders, m_showRepaintCounter);
941
942    return layerChanged;
943}
944
945bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer& layer, CompositingChangeRepaint shouldRepaint)
946{
947    bool layerChanged = updateBacking(layer, shouldRepaint);
948
949    // See if we need content or clipping layers. Methods called here should assume
950    // that the compositing state of descendant layers has not been updated yet.
951    if (layer.backing() && layer.backing()->updateConfiguration())
952        layerChanged = true;
953
954    return layerChanged;
955}
956
957void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer& layer)
958{
959    // If the renderer is not attached yet, no need to repaint.
960    if (&layer.renderer() != &m_renderView && !layer.renderer().parent())
961        return;
962
963    RenderLayerModelObject* repaintContainer = layer.renderer().containerForRepaint();
964    if (!repaintContainer)
965        repaintContainer = &m_renderView;
966
967    layer.repaintIncludingNonCompositingDescendants(repaintContainer);
968    if (repaintContainer == &m_renderView) {
969        // The contents of this layer may be moving between the window
970        // and a GraphicsLayer, so we need to make sure the window system
971        // synchronizes those changes on the screen.
972        m_renderView.frameView().setNeedsOneShotDrawingSynchronization();
973    }
974}
975
976// This method assumes that layout is up-to-date, unlike repaintOnCompositingChange().
977void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer& layer, const LayoutRect& rect)
978{
979    RenderLayer* compositedAncestor = layer.enclosingCompositingLayerForRepaint(ExcludeSelf);
980    if (compositedAncestor) {
981        ASSERT(compositedAncestor->backing());
982        LayoutRect repaintRect = rect;
983        repaintRect.move(layer.offsetFromAncestor(compositedAncestor));
984        compositedAncestor->setBackingNeedsRepaintInRect(repaintRect);
985    }
986
987    // The contents of this layer may be moving from a GraphicsLayer to the window,
988    // so we need to make sure the window system synchronizes those changes on the screen.
989    if (compositedAncestor == m_renderView.layer())
990        m_renderView.frameView().setNeedsOneShotDrawingSynchronization();
991}
992
993void RenderLayerCompositor::layerWasAdded(RenderLayer&, RenderLayer&)
994{
995    setCompositingLayersNeedRebuild();
996}
997
998void RenderLayerCompositor::layerWillBeRemoved(RenderLayer& parent, RenderLayer& child)
999{
1000    if (!child.isComposited() || parent.renderer().documentBeingDestroyed())
1001        return;
1002
1003    removeFromScrollCoordinatedLayers(child);
1004    repaintInCompositedAncestor(child, child.backing()->compositedBounds());
1005
1006    setCompositingParent(child, nullptr);
1007    setCompositingLayersNeedRebuild();
1008}
1009
1010RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer& layer) const
1011{
1012    for (RenderLayer* parent = layer.parent(); parent; parent = parent->parent()) {
1013        if (parent->isStackingContainer())
1014            return nullptr;
1015        if (parent->renderer().hasClipOrOverflowClip())
1016            return parent;
1017    }
1018    return nullptr;
1019}
1020
1021void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer& layer, IntRect& layerBounds, bool& boundsComputed)
1022{
1023    if (layer.isRootLayer())
1024        return;
1025
1026    if (!boundsComputed) {
1027        // FIXME: If this layer's overlap bounds include its children, we don't need to add its
1028        // children's bounds to the overlap map.
1029        layerBounds = enclosingIntRect(overlapMap.geometryMap().absoluteRect(layer.overlapBounds()));
1030        // Empty rects never intersect, but we need them to for the purposes of overlap testing.
1031        if (layerBounds.isEmpty())
1032            layerBounds.setSize(IntSize(1, 1));
1033        boundsComputed = true;
1034    }
1035
1036    IntRect clipRect = pixelSnappedIntRect(layer.backgroundClipRect(RenderLayer::ClipRectsContext(&rootRenderLayer(), AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
1037
1038    // On iOS, pageScaleFactor() is not applied by RenderView, so we should not scale here.
1039    // FIXME: Set Settings::delegatesPageScaling to true for iOS.
1040#if !PLATFORM(IOS)
1041    const Settings& settings = m_renderView.frameView().frame().settings();
1042    if (!settings.delegatesPageScaling())
1043        clipRect.scale(pageScaleFactor());
1044#endif
1045    clipRect.intersect(layerBounds);
1046    overlapMap.add(&layer, clipRect);
1047}
1048
1049void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, RenderLayer& layer, RenderLayer* ancestorLayer)
1050{
1051    if (!canBeComposited(layer) || overlapMap.contains(&layer))
1052        return;
1053
1054    // A null ancestorLayer is an indication that 'layer' has already been pushed.
1055    if (ancestorLayer)
1056        overlapMap.geometryMap().pushMappingsToAncestor(&layer, ancestorLayer);
1057
1058    IntRect bounds;
1059    bool haveComputedBounds = false;
1060    addToOverlapMap(overlapMap, layer, bounds, haveComputedBounds);
1061
1062#if !ASSERT_DISABLED
1063    LayerListMutationDetector mutationChecker(&layer);
1064#endif
1065
1066    if (layer.isStackingContainer()) {
1067        if (Vector<RenderLayer*>* negZOrderList = layer.negZOrderList()) {
1068            for (size_t i = 0, size = negZOrderList->size(); i < size; ++i)
1069                addToOverlapMapRecursive(overlapMap, *negZOrderList->at(i), &layer);
1070        }
1071    }
1072
1073    if (Vector<RenderLayer*>* normalFlowList = layer.normalFlowList()) {
1074        for (size_t i = 0, size = normalFlowList->size(); i < size; ++i)
1075            addToOverlapMapRecursive(overlapMap, *normalFlowList->at(i), &layer);
1076    }
1077
1078    if (layer.isStackingContainer()) {
1079        if (Vector<RenderLayer*>* posZOrderList = layer.posZOrderList()) {
1080            for (size_t i = 0, size = posZOrderList->size(); i < size; ++i)
1081                addToOverlapMapRecursive(overlapMap, *posZOrderList->at(i), &layer);
1082        }
1083    }
1084
1085    if (ancestorLayer)
1086        overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
1087}
1088
1089void RenderLayerCompositor::computeCompositingRequirementsForNamedFlowFixed(RenderLayer& layer, OverlapMap* overlapMap, CompositingState& childState, bool& layersChanged, bool& anyDescendantHas3DTransform)
1090{
1091    if (!layer.isRootLayer())
1092        return;
1093
1094    if (!layer.renderer().view().hasRenderNamedFlowThreads())
1095        return;
1096
1097    Vector<RenderLayer*> fixedLayers;
1098    layer.renderer().view().flowThreadController().collectFixedPositionedLayers(fixedLayers);
1099
1100    for (size_t i = 0; i < fixedLayers.size(); ++i) {
1101        RenderLayer* fixedLayer = fixedLayers.at(i);
1102        computeCompositingRequirements(&layer, *fixedLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
1103    }
1104}
1105
1106//  Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
1107//  For the z-order children of a compositing layer:
1108//      If a child layers has a compositing layer, then all subsequent layers must
1109//      be compositing in order to render above that layer.
1110//
1111//      If a child in the negative z-order list is compositing, then the layer itself
1112//      must be compositing so that its contents render over that child.
1113//      This implies that its positive z-index children must also be compositing.
1114//
1115void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer& layer, OverlapMap* overlapMap, CompositingState& compositingState, bool& layersChanged, bool& descendantHas3DTransform)
1116{
1117    layer.updateDescendantDependentFlags();
1118    layer.updateLayerListsIfNeeded();
1119
1120    if (layer.isFlowThreadCollectingGraphicsLayersUnderRegions()) {
1121        RenderFlowThread& flowThread = toRenderFlowThread(layer.renderer());
1122        layer.setHasCompositingDescendant(flowThread.hasCompositingRegionDescendant());
1123
1124        // Before returning, we need to update the lists of all child layers. This is required because,
1125        // if this flow thread will not be painted (for instance because of having no regions, or only invalid regions),
1126        // the child layers will never have their lists updated (which would normally happen during painting).
1127        layer.updateDescendantsLayerListsIfNeeded(true);
1128
1129        return;
1130    }
1131
1132    if (overlapMap)
1133        overlapMap->geometryMap().pushMappingsToAncestor(&layer, ancestorLayer);
1134
1135    // Clear the flag
1136    layer.setHasCompositingDescendant(false);
1137    layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::None);
1138
1139    // Check if the layer needs to be composited for non-indirect reasons (ex. 3D transform).
1140    // We use this value to avoid checking the overlap-map, if we know for sure the layer
1141    // is already going to be composited for other reasons.
1142    bool willBeComposited = needsToBeComposited(layer);
1143
1144    RenderLayer::IndirectCompositingReason compositingReason = compositingState.m_subtreeIsCompositing ? RenderLayer::IndirectCompositingReason::Stacking : RenderLayer::IndirectCompositingReason::None;
1145    bool haveComputedBounds = false;
1146    IntRect absBounds;
1147
1148    // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map
1149    if (!willBeComposited && overlapMap && !overlapMap->isEmpty() && compositingState.m_testingOverlap) {
1150        // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
1151        absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer.overlapBounds()));
1152
1153        // Empty rects never intersect, but we need them to for the purposes of overlap testing.
1154        if (absBounds.isEmpty())
1155            absBounds.setSize(IntSize(1, 1));
1156        haveComputedBounds = true;
1157        compositingReason = overlapMap->overlapsLayers(absBounds) ? RenderLayer::IndirectCompositingReason::Overlap : RenderLayer::IndirectCompositingReason::None;
1158    }
1159
1160#if ENABLE(VIDEO)
1161    // Video is special. It's the only RenderLayer type that can both have
1162    // RenderLayer children and whose children can't use its backing to render
1163    // into. These children (the controls) always need to be promoted into their
1164    // own layers to draw on top of the accelerated video.
1165    if (compositingState.m_compositingAncestor && compositingState.m_compositingAncestor->renderer().isVideo())
1166        compositingReason = RenderLayer::IndirectCompositingReason::Overlap;
1167#endif
1168
1169    layer.setIndirectCompositingReason(compositingReason);
1170
1171    // Check if the computed indirect reason will force the layer to become composited.
1172    if (!willBeComposited && layer.mustCompositeForIndirectReasons() && canBeComposited(layer))
1173        willBeComposited = true;
1174    ASSERT(willBeComposited == needsToBeComposited(layer));
1175
1176    // The children of this layer don't need to composite, unless there is
1177    // a compositing layer among them, so start by inheriting the compositing
1178    // ancestor with m_subtreeIsCompositing set to false.
1179    CompositingState childState(compositingState);
1180    childState.m_subtreeIsCompositing = false;
1181#if ENABLE(CSS_COMPOSITING)
1182    childState.m_hasNotIsolatedCompositedBlendingDescendants = false;
1183#endif
1184
1185    if (willBeComposited) {
1186        // Tell the parent it has compositing descendants.
1187        compositingState.m_subtreeIsCompositing = true;
1188        // This layer now acts as the ancestor for kids.
1189        childState.m_compositingAncestor = &layer;
1190
1191        if (overlapMap)
1192            overlapMap->pushCompositingContainer();
1193        // This layer is going to be composited, so children can safely ignore the fact that there's an
1194        // animation running behind this layer, meaning they can rely on the overlap map testing again.
1195        childState.m_testingOverlap = true;
1196    }
1197
1198#if !ASSERT_DISABLED
1199    LayerListMutationDetector mutationChecker(&layer);
1200#endif
1201
1202    bool anyDescendantHas3DTransform = false;
1203
1204    if (layer.isStackingContainer()) {
1205        if (Vector<RenderLayer*>* negZOrderList = layer.negZOrderList()) {
1206            for (size_t i = 0, size = negZOrderList->size(); i < size; ++i) {
1207                computeCompositingRequirements(&layer, *negZOrderList->at(i), overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
1208
1209                // If we have to make a layer for this child, make one now so we can have a contents layer
1210                // (since we need to ensure that the -ve z-order child renders underneath our contents).
1211                if (!willBeComposited && childState.m_subtreeIsCompositing) {
1212                    // make layer compositing
1213                    layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::BackgroundLayer);
1214                    childState.m_compositingAncestor = &layer;
1215                    if (overlapMap)
1216                        overlapMap->pushCompositingContainer();
1217                    // This layer is going to be composited, so children can safely ignore the fact that there's an
1218                    // animation running behind this layer, meaning they can rely on the overlap map testing again
1219                    childState.m_testingOverlap = true;
1220                    willBeComposited = true;
1221                }
1222            }
1223        }
1224    }
1225
1226    if (layer.renderer().isRenderNamedFlowFragmentContainer()) {
1227        // We are going to collect layers from the RenderFlowThread into the GraphicsLayer of the parent of the
1228        // anonymous RenderRegion, but first we need to make sure that the parent itself of the region is going to
1229        // have a composited layer. We only want to make regions composited when there's an actual layer that we
1230        // need to move to that region.
1231        computeRegionCompositingRequirements(toRenderBlockFlow(layer.renderer()).renderNamedFlowFragment(), overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
1232    }
1233
1234
1235    if (Vector<RenderLayer*>* normalFlowList = layer.normalFlowList()) {
1236        for (size_t i = 0, size = normalFlowList->size(); i < size; ++i)
1237            computeCompositingRequirements(&layer, *normalFlowList->at(i), overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
1238    }
1239
1240    if (layer.isStackingContainer()) {
1241        if (Vector<RenderLayer*>* posZOrderList = layer.posZOrderList()) {
1242            for (size_t i = 0, size = posZOrderList->size(); i < size; ++i)
1243                computeCompositingRequirements(&layer, *posZOrderList->at(i), overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
1244        }
1245    }
1246
1247    if (layer.isRootLayer())
1248        computeCompositingRequirementsForNamedFlowFixed(layer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
1249
1250    // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
1251    if (layer.isRootLayer()) {
1252        if (inCompositingMode() && m_hasAcceleratedCompositing)
1253            willBeComposited = true;
1254    }
1255
1256    ASSERT(willBeComposited == needsToBeComposited(layer));
1257
1258    // All layers (even ones that aren't being composited) need to get added to
1259    // the overlap map. Layers that do not composite will draw into their
1260    // compositing ancestor's backing, and so are still considered for overlap.
1261    if (overlapMap && childState.m_compositingAncestor && !childState.m_compositingAncestor->isRootLayer())
1262        addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
1263
1264#if ENABLE(CSS_COMPOSITING)
1265    layer.setHasNotIsolatedCompositedBlendingDescendants(childState.m_hasNotIsolatedCompositedBlendingDescendants);
1266    ASSERT(!layer.hasNotIsolatedCompositedBlendingDescendants() || layer.hasNotIsolatedBlendingDescendants());
1267#endif
1268    // Now check for reasons to become composited that depend on the state of descendant layers.
1269    RenderLayer::IndirectCompositingReason indirectCompositingReason;
1270    if (!willBeComposited && canBeComposited(layer)
1271        && requiresCompositingForIndirectReason(layer.renderer(), childState.m_subtreeIsCompositing, anyDescendantHas3DTransform, indirectCompositingReason)) {
1272        layer.setIndirectCompositingReason(indirectCompositingReason);
1273        childState.m_compositingAncestor = &layer;
1274        if (overlapMap) {
1275            overlapMap->pushCompositingContainer();
1276            addToOverlapMapRecursive(*overlapMap, layer);
1277        }
1278        willBeComposited = true;
1279    }
1280
1281    ASSERT(willBeComposited == needsToBeComposited(layer));
1282    if (layer.reflectionLayer()) {
1283        // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
1284        layer.reflectionLayer()->setIndirectCompositingReason(willBeComposited ? RenderLayer::IndirectCompositingReason::Stacking : RenderLayer::IndirectCompositingReason::None);
1285    }
1286
1287    // Subsequent layers in the parent stacking context also need to composite.
1288    if (childState.m_subtreeIsCompositing)
1289        compositingState.m_subtreeIsCompositing = true;
1290
1291    // Set the flag to say that this SC has compositing children.
1292    layer.setHasCompositingDescendant(childState.m_subtreeIsCompositing);
1293
1294    // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping,
1295    // so test that again.
1296    bool isCompositedClippingLayer = canBeComposited(layer) && clipsCompositingDescendants(layer);
1297
1298    // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.
1299    // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because
1300    // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.
1301    if ((!childState.m_testingOverlap && !isCompositedClippingLayer) || isRunningAcceleratedTransformAnimation(layer.renderer()))
1302        compositingState.m_testingOverlap = false;
1303
1304    if (isCompositedClippingLayer) {
1305        if (!willBeComposited) {
1306            childState.m_compositingAncestor = &layer;
1307            if (overlapMap) {
1308                overlapMap->pushCompositingContainer();
1309                addToOverlapMapRecursive(*overlapMap, layer);
1310            }
1311            willBeComposited = true;
1312         }
1313    }
1314
1315#if ENABLE(CSS_COMPOSITING)
1316    if ((willBeComposited && layer.hasBlendMode())
1317        || (layer.hasNotIsolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending()))
1318        compositingState.m_hasNotIsolatedCompositedBlendingDescendants = true;
1319#endif
1320
1321    if (overlapMap && childState.m_compositingAncestor == &layer && !layer.isRootLayer())
1322        overlapMap->popCompositingContainer();
1323
1324    // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
1325    // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode
1326    // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
1327    if (layer.isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode && !hasAnyAdditionalCompositedLayers(layer)) {
1328        // Don't drop out of compositing on iOS, because we may flash. See <rdar://problem/8348337>.
1329#if !PLATFORM(IOS)
1330        enableCompositingMode(false);
1331        willBeComposited = false;
1332#endif
1333    }
1334
1335    // If the layer is going into compositing mode, repaint its old location.
1336    ASSERT(willBeComposited == needsToBeComposited(layer));
1337    if (!layer.isComposited() && willBeComposited)
1338        repaintOnCompositingChange(layer);
1339
1340    // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
1341    if (updateBacking(layer, CompositingChangeRepaintNow))
1342        layersChanged = true;
1343
1344    if (layer.reflectionLayer() && updateLayerCompositingState(*layer.reflectionLayer(), CompositingChangeRepaintNow))
1345        layersChanged = true;
1346
1347    descendantHas3DTransform |= anyDescendantHas3DTransform || layer.has3DTransform();
1348
1349    if (overlapMap)
1350        overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer);
1351}
1352
1353void RenderLayerCompositor::computeRegionCompositingRequirements(RenderNamedFlowFragment* region, OverlapMap* overlapMap, CompositingState& childState, bool& layersChanged, bool& anyDescendantHas3DTransform)
1354{
1355    if (!region->isValid())
1356        return;
1357
1358    RenderFlowThread* flowThread = region->flowThread();
1359
1360    if (overlapMap)
1361        overlapMap->geometryMap().pushRenderFlowThread(flowThread);
1362
1363    if (const RenderLayerList* layerList = flowThread->getLayerListForRegion(region)) {
1364        for (size_t i = 0, listSize = layerList->size(); i < listSize; ++i) {
1365            RenderLayer& curLayer = *layerList->at(i);
1366            ASSERT(flowThread->regionForCompositedLayer(curLayer) == region);
1367            computeCompositingRequirements(flowThread->layer(), curLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
1368        }
1369    }
1370
1371    if (overlapMap)
1372        overlapMap->geometryMap().popMappingsToAncestor(&region->layerOwner());
1373}
1374
1375void RenderLayerCompositor::setCompositingParent(RenderLayer& childLayer, RenderLayer* parentLayer)
1376{
1377    ASSERT(!parentLayer || childLayer.ancestorCompositingLayer() == parentLayer);
1378    ASSERT(childLayer.isComposited());
1379
1380    // It's possible to be called with a parent that isn't yet composited when we're doing
1381    // partial updates as required by painting or hit testing. Just bail in that case;
1382    // we'll do a full layer update soon.
1383    if (!parentLayer || !parentLayer->isComposited())
1384        return;
1385
1386    if (parentLayer) {
1387        GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers();
1388        GraphicsLayer* hostedLayer = childLayer.backing()->childForSuperlayers();
1389
1390        hostingLayer->addChild(hostedLayer);
1391    } else
1392        childLayer.backing()->childForSuperlayers()->removeFromParent();
1393}
1394
1395void RenderLayerCompositor::removeCompositedChildren(RenderLayer& layer)
1396{
1397    ASSERT(layer.isComposited());
1398
1399    layer.backing()->parentForSublayers()->removeAllChildren();
1400}
1401
1402#if ENABLE(VIDEO)
1403bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo& video) const
1404{
1405    if (!m_hasAcceleratedCompositing)
1406        return false;
1407
1408    return video.supportsAcceleratedRendering();
1409}
1410#endif
1411
1412void RenderLayerCompositor::rebuildCompositingLayerTreeForNamedFlowFixed(RenderLayer& layer, Vector<GraphicsLayer*>& childGraphicsLayersOfEnclosingLayer, int depth)
1413{
1414    if (!layer.isRootLayer())
1415        return;
1416
1417    if (!layer.renderer().view().hasRenderNamedFlowThreads())
1418        return;
1419
1420    Vector<RenderLayer*> fixedLayers;
1421    layer.renderer().view().flowThreadController().collectFixedPositionedLayers(fixedLayers);
1422
1423    for (size_t i = 0; i < fixedLayers.size(); ++i) {
1424        RenderLayer* fixedLayer = fixedLayers.at(i);
1425        rebuildCompositingLayerTree(*fixedLayer, childGraphicsLayersOfEnclosingLayer, depth);
1426    }
1427}
1428
1429void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer& layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth)
1430{
1431    // Make the layer compositing if necessary, and set up clipping and content layers.
1432    // Note that we can only do work here that is independent of whether the descendant layers
1433    // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
1434
1435    // Do not iterate the RenderFlowThread directly. We are going to collect composited layers as part of regions.
1436    if (layer.isFlowThreadCollectingGraphicsLayersUnderRegions())
1437        return;
1438
1439    RenderLayerBacking* layerBacking = layer.backing();
1440    if (layerBacking) {
1441        // The compositing state of all our children has been updated already, so now
1442        // we can compute and cache the composited bounds for this layer.
1443        layerBacking->updateCompositedBounds();
1444
1445        if (RenderLayer* reflection = layer.reflectionLayer()) {
1446            if (reflection->backing())
1447                reflection->backing()->updateCompositedBounds();
1448        }
1449
1450        if (layerBacking->updateConfiguration())
1451            layerBacking->updateDebugIndicators(m_showDebugBorders, m_showRepaintCounter);
1452
1453        layerBacking->updateGeometry();
1454
1455        if (!layer.parent())
1456            updateRootLayerPosition();
1457
1458#if !LOG_DISABLED
1459        logLayerInfo(layer, depth);
1460#else
1461        UNUSED_PARAM(depth);
1462#endif
1463        if (layerBacking->hasUnpositionedOverflowControlsLayers())
1464            layer.positionNewlyCreatedOverflowControls();
1465    }
1466
1467    // If this layer has backing, then we are collecting its children, otherwise appending
1468    // to the compositing child list of an enclosing layer.
1469    Vector<GraphicsLayer*> layerChildren;
1470    Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
1471
1472#if !ASSERT_DISABLED
1473    LayerListMutationDetector mutationChecker(&layer);
1474#endif
1475
1476    if (layer.isStackingContainer()) {
1477        if (Vector<RenderLayer*>* negZOrderList = layer.negZOrderList()) {
1478            for (size_t i = 0, size = negZOrderList->size(); i < size; ++i)
1479                rebuildCompositingLayerTree(*negZOrderList->at(i), childList, depth + 1);
1480        }
1481
1482        // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
1483        if (layerBacking && layerBacking->foregroundLayer())
1484            childList.append(layerBacking->foregroundLayer());
1485    }
1486
1487    if (layer.renderer().isRenderNamedFlowFragmentContainer())
1488        rebuildRegionCompositingLayerTree(toRenderBlockFlow(layer.renderer()).renderNamedFlowFragment(), layerChildren, depth + 1);
1489
1490    if (Vector<RenderLayer*>* normalFlowList = layer.normalFlowList()) {
1491        for (size_t i = 0, size = normalFlowList->size(); i < size; ++i)
1492            rebuildCompositingLayerTree(*normalFlowList->at(i), childList, depth + 1);
1493    }
1494
1495    if (layer.isStackingContainer()) {
1496        if (Vector<RenderLayer*>* posZOrderList = layer.posZOrderList()) {
1497            for (size_t i = 0, size = posZOrderList->size(); i < size; ++i)
1498                rebuildCompositingLayerTree(*posZOrderList->at(i), childList, depth + 1);
1499        }
1500    }
1501
1502    if (layer.isRootLayer())
1503        rebuildCompositingLayerTreeForNamedFlowFixed(layer, childList, depth + 1);
1504
1505    if (layerBacking) {
1506        bool parented = false;
1507        if (layer.renderer().isWidget())
1508            parented = parentFrameContentLayers(toRenderWidget(&layer.renderer()));
1509
1510        if (!parented)
1511            layerBacking->parentForSublayers()->setChildren(layerChildren);
1512
1513        // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
1514        // Otherwise, the overflow control layers are normal children.
1515        if (!layerBacking->hasClippingLayer() && !layerBacking->hasScrollingLayer()) {
1516            if (GraphicsLayer* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) {
1517                overflowControlLayer->removeFromParent();
1518                layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1519            }
1520
1521            if (GraphicsLayer* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) {
1522                overflowControlLayer->removeFromParent();
1523                layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1524            }
1525
1526            if (GraphicsLayer* overflowControlLayer = layerBacking->layerForScrollCorner()) {
1527                overflowControlLayer->removeFromParent();
1528                layerBacking->parentForSublayers()->addChild(overflowControlLayer);
1529            }
1530        }
1531
1532        childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
1533    }
1534
1535    if (RenderLayerBacking* layerBacking = layer.backing())
1536        layerBacking->updateAfterDescendents();
1537}
1538
1539void RenderLayerCompositor::rebuildRegionCompositingLayerTree(RenderNamedFlowFragment* region, Vector<GraphicsLayer*>& childList, int depth)
1540{
1541    if (!region->isValid())
1542        return;
1543
1544    RenderFlowThread* flowThread = region->flowThread();
1545    ASSERT(flowThread->collectsGraphicsLayersUnderRegions());
1546    if (const RenderLayerList* layerList = flowThread->getLayerListForRegion(region)) {
1547        for (size_t i = 0, listSize = layerList->size(); i < listSize; ++i) {
1548            RenderLayer& curLayer = *layerList->at(i);
1549            ASSERT(flowThread->regionForCompositedLayer(curLayer) == region);
1550            rebuildCompositingLayerTree(curLayer, childList, depth + 1);
1551        }
1552    }
1553}
1554
1555void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
1556{
1557    if (m_overflowControlsHostLayer)
1558        m_overflowControlsHostLayer->setPosition(contentsOffset);
1559}
1560
1561void RenderLayerCompositor::frameViewDidChangeSize()
1562{
1563    if (m_clipLayer) {
1564        const FrameView& frameView = m_renderView.frameView();
1565        m_clipLayer->setSize(frameView.unscaledVisibleContentSizeIncludingObscuredArea());
1566        m_clipLayer->setPosition(positionForClipLayer());
1567
1568        frameViewDidScroll();
1569        updateOverflowControlsLayers();
1570
1571#if ENABLE(RUBBER_BANDING)
1572        if (m_layerForOverhangAreas) {
1573            m_layerForOverhangAreas->setSize(frameView.frameRect().size());
1574            m_layerForOverhangAreas->setPosition(FloatPoint(0, m_renderView.frameView().topContentInset()));
1575        }
1576#endif
1577    }
1578}
1579
1580bool RenderLayerCompositor::hasCoordinatedScrolling() const
1581{
1582    ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator();
1583    return scrollingCoordinator && scrollingCoordinator->coordinatesScrollingForFrameView(&m_renderView.frameView());
1584}
1585
1586void RenderLayerCompositor::updateScrollLayerPosition()
1587{
1588    ASSERT(m_scrollLayer);
1589
1590    FrameView& frameView = m_renderView.frameView();
1591    IntPoint scrollPosition = frameView.scrollPosition();
1592
1593    m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
1594
1595    if (GraphicsLayer* fixedBackgroundLayer = fixedRootBackgroundLayer())
1596        fixedBackgroundLayer->setPosition(toLayoutPoint(frameView.scrollOffsetForFixedPosition()));
1597}
1598
1599FloatPoint RenderLayerCompositor::positionForClipLayer() const
1600{
1601    return FloatPoint(0, FrameView::yPositionForInsetClipLayer(m_renderView.frameView().scrollPosition(), m_renderView.frameView().topContentInset()));
1602}
1603
1604void RenderLayerCompositor::frameViewDidScroll()
1605{
1606    if (!m_scrollLayer)
1607        return;
1608
1609    // If there's a scrolling coordinator that manages scrolling for this frame view,
1610    // it will also manage updating the scroll layer position.
1611    if (hasCoordinatedScrolling()) {
1612        // We have to schedule a flush in order for the main TiledBacking to update its tile coverage.
1613        scheduleLayerFlushNow();
1614        return;
1615    }
1616
1617    updateScrollLayerPosition();
1618}
1619
1620void RenderLayerCompositor::frameViewDidAddOrRemoveScrollbars()
1621{
1622    updateOverflowControlsLayers();
1623}
1624
1625void RenderLayerCompositor::frameViewDidLayout()
1626{
1627    RenderLayerBacking* renderViewBacking = m_renderView.layer()->backing();
1628    if (renderViewBacking)
1629        renderViewBacking->adjustTiledBackingCoverage();
1630}
1631
1632void RenderLayerCompositor::rootFixedBackgroundsChanged()
1633{
1634    RenderLayerBacking* renderViewBacking = m_renderView.layer()->backing();
1635    if (renderViewBacking && renderViewBacking->usingTiledBacking())
1636        setCompositingLayersNeedRebuild();
1637}
1638
1639void RenderLayerCompositor::scrollingLayerDidChange(RenderLayer& layer)
1640{
1641    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
1642        scrollingCoordinator->scrollableAreaScrollLayerDidChange(&layer);
1643}
1644
1645void RenderLayerCompositor::fixedRootBackgroundLayerChanged()
1646{
1647    if (m_renderView.documentBeingDestroyed())
1648        return;
1649
1650    if (m_renderView.layer()->isComposited())
1651        updateScrollCoordinatedStatus(*m_renderView.layer());
1652}
1653
1654String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
1655{
1656    updateCompositingLayers(CompositingUpdateAfterLayout);
1657
1658    if (!m_rootContentLayer)
1659        return String();
1660
1661    flushPendingLayerChanges(true);
1662
1663    LayerTreeAsTextBehavior layerTreeBehavior = LayerTreeAsTextBehaviorNormal;
1664    if (flags & LayerTreeFlagsIncludeDebugInfo)
1665        layerTreeBehavior |= LayerTreeAsTextDebug;
1666    if (flags & LayerTreeFlagsIncludeVisibleRects)
1667        layerTreeBehavior |= LayerTreeAsTextIncludeVisibleRects;
1668    if (flags & LayerTreeFlagsIncludeTileCaches)
1669        layerTreeBehavior |= LayerTreeAsTextIncludeTileCaches;
1670    if (flags & LayerTreeFlagsIncludeRepaintRects)
1671        layerTreeBehavior |= LayerTreeAsTextIncludeRepaintRects;
1672    if (flags & LayerTreeFlagsIncludePaintingPhases)
1673        layerTreeBehavior |= LayerTreeAsTextIncludePaintingPhases;
1674    if (flags & LayerTreeFlagsIncludeContentLayers)
1675        layerTreeBehavior |= LayerTreeAsTextIncludeContentLayers;
1676
1677    // We skip dumping the scroll and clip layers to keep layerTreeAsText output
1678    // similar between platforms.
1679    String layerTreeText = m_rootContentLayer->layerTreeAsText(layerTreeBehavior);
1680
1681    // Dump an empty layer tree only if the only composited layer is the main frame's tiled backing,
1682    // so that tests expecting us to drop out of accelerated compositing when there are no layers succeed.
1683    if (!hasAnyAdditionalCompositedLayers(rootRenderLayer()) && mainFrameBackingIsTiled() && !(layerTreeBehavior & LayerTreeAsTextIncludeTileCaches))
1684        layerTreeText = "";
1685
1686    // The true root layer is not included in the dump, so if we want to report
1687    // its repaint rects, they must be included here.
1688    if (flags & LayerTreeFlagsIncludeRepaintRects)
1689        return m_renderView.frameView().trackedRepaintRectsAsText() + layerTreeText;
1690
1691    return layerTreeText;
1692}
1693
1694RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderWidget* renderer)
1695{
1696    if (Document* contentDocument = renderer->frameOwnerElement().contentDocument()) {
1697        if (RenderView* view = contentDocument->renderView())
1698            return &view->compositor();
1699    }
1700    return 0;
1701}
1702
1703bool RenderLayerCompositor::parentFrameContentLayers(RenderWidget* renderer)
1704{
1705    RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
1706    if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
1707        return false;
1708
1709    RenderLayer* layer = renderer->layer();
1710    if (!layer->isComposited())
1711        return false;
1712
1713    RenderLayerBacking* backing = layer->backing();
1714    GraphicsLayer* hostingLayer = backing->parentForSublayers();
1715    GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
1716    if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
1717        hostingLayer->removeAllChildren();
1718        hostingLayer->addChild(rootLayer);
1719    }
1720    return true;
1721}
1722
1723// This just updates layer geometry without changing the hierarchy.
1724void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer& layer, int depth)
1725{
1726    if (RenderLayerBacking* layerBacking = layer.backing()) {
1727        // The compositing state of all our children has been updated already, so now
1728        // we can compute and cache the composited bounds for this layer.
1729        layerBacking->updateCompositedBounds();
1730
1731        if (RenderLayer* reflection = layer.reflectionLayer()) {
1732            if (reflection->backing())
1733                reflection->backing()->updateCompositedBounds();
1734        }
1735
1736        layerBacking->updateConfiguration();
1737        layerBacking->updateGeometry();
1738
1739        if (!layer.parent())
1740            updateRootLayerPosition();
1741
1742#if !LOG_DISABLED
1743        logLayerInfo(layer, depth);
1744#else
1745        UNUSED_PARAM(depth);
1746#endif
1747    }
1748
1749#if !ASSERT_DISABLED
1750    LayerListMutationDetector mutationChecker(&layer);
1751#endif
1752
1753    if (layer.isStackingContainer()) {
1754        if (Vector<RenderLayer*>* negZOrderList = layer.negZOrderList()) {
1755            for (size_t i = 0, size = negZOrderList->size(); i < size; ++i)
1756                updateLayerTreeGeometry(*negZOrderList->at(i), depth + 1);
1757        }
1758    }
1759
1760    if (Vector<RenderLayer*>* normalFlowList = layer.normalFlowList()) {
1761        for (size_t i = 0, size = normalFlowList->size(); i < size; ++i)
1762            updateLayerTreeGeometry(*normalFlowList->at(i), depth + 1);
1763    }
1764
1765    if (layer.isStackingContainer()) {
1766        if (Vector<RenderLayer*>* posZOrderList = layer.posZOrderList()) {
1767            for (size_t i = 0, size = posZOrderList->size(); i < size; ++i)
1768                updateLayerTreeGeometry(*posZOrderList->at(i), depth + 1);
1769        }
1770    }
1771
1772    if (RenderLayerBacking* layerBacking = layer.backing())
1773        layerBacking->updateAfterDescendents();
1774}
1775
1776// Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
1777void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer& compositingAncestor, RenderLayer& layer, bool compositedChildrenOnly)
1778{
1779    if (&layer != &compositingAncestor) {
1780        if (RenderLayerBacking* layerBacking = layer.backing()) {
1781            layerBacking->updateCompositedBounds();
1782
1783            if (RenderLayer* reflection = layer.reflectionLayer()) {
1784                if (reflection->backing())
1785                    reflection->backing()->updateCompositedBounds();
1786            }
1787
1788            layerBacking->updateGeometry();
1789            if (compositedChildrenOnly) {
1790                layerBacking->updateAfterDescendents();
1791                return;
1792            }
1793        }
1794    }
1795
1796    if (layer.reflectionLayer())
1797        updateCompositingDescendantGeometry(compositingAncestor, *layer.reflectionLayer(), compositedChildrenOnly);
1798
1799    if (!layer.hasCompositingDescendant())
1800        return;
1801
1802#if !ASSERT_DISABLED
1803    LayerListMutationDetector mutationChecker(&layer);
1804#endif
1805
1806    if (layer.isStackingContainer()) {
1807        if (Vector<RenderLayer*>* negZOrderList = layer.negZOrderList()) {
1808            size_t listSize = negZOrderList->size();
1809            for (size_t i = 0; i < listSize; ++i)
1810                updateCompositingDescendantGeometry(compositingAncestor, *negZOrderList->at(i), compositedChildrenOnly);
1811        }
1812    }
1813
1814    if (Vector<RenderLayer*>* normalFlowList = layer.normalFlowList()) {
1815        size_t listSize = normalFlowList->size();
1816        for (size_t i = 0; i < listSize; ++i)
1817            updateCompositingDescendantGeometry(compositingAncestor, *normalFlowList->at(i), compositedChildrenOnly);
1818    }
1819
1820    if (layer.isStackingContainer()) {
1821        if (Vector<RenderLayer*>* posZOrderList = layer.posZOrderList()) {
1822            size_t listSize = posZOrderList->size();
1823            for (size_t i = 0; i < listSize; ++i)
1824                updateCompositingDescendantGeometry(compositingAncestor, *posZOrderList->at(i), compositedChildrenOnly);
1825        }
1826    }
1827
1828    if (&layer != &compositingAncestor) {
1829        if (RenderLayerBacking* layerBacking = layer.backing())
1830            layerBacking->updateAfterDescendents();
1831    }
1832}
1833
1834void RenderLayerCompositor::repaintCompositedLayers()
1835{
1836    recursiveRepaintLayer(rootRenderLayer());
1837}
1838
1839void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer& layer)
1840{
1841    // FIXME: This method does not work correctly with transforms.
1842    if (layer.isComposited() && !layer.backing()->paintsIntoCompositedAncestor())
1843        layer.setBackingNeedsRepaint();
1844
1845#if !ASSERT_DISABLED
1846    LayerListMutationDetector mutationChecker(&layer);
1847#endif
1848
1849    if (layer.hasCompositingDescendant()) {
1850        if (Vector<RenderLayer*>* negZOrderList = layer.negZOrderList()) {
1851            for (size_t i = 0, size = negZOrderList->size(); i < size; ++i)
1852                recursiveRepaintLayer(*negZOrderList->at(i));
1853        }
1854
1855        if (Vector<RenderLayer*>* posZOrderList = layer.posZOrderList()) {
1856            for (size_t i = 0, size = posZOrderList->size(); i < size; ++i)
1857                recursiveRepaintLayer(*posZOrderList->at(i));
1858        }
1859    }
1860    if (Vector<RenderLayer*>* normalFlowList = layer.normalFlowList()) {
1861        for (size_t i = 0, size = normalFlowList->size(); i < size; ++i)
1862            recursiveRepaintLayer(*normalFlowList->at(i));
1863    }
1864}
1865
1866RenderLayer& RenderLayerCompositor::rootRenderLayer() const
1867{
1868    return *m_renderView.layer();
1869}
1870
1871GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
1872{
1873    if (m_overflowControlsHostLayer)
1874        return m_overflowControlsHostLayer.get();
1875    return m_rootContentLayer.get();
1876}
1877
1878GraphicsLayer* RenderLayerCompositor::scrollLayer() const
1879{
1880    return m_scrollLayer.get();
1881}
1882
1883GraphicsLayer* RenderLayerCompositor::clipLayer() const
1884{
1885    return m_clipLayer.get();
1886}
1887
1888GraphicsLayer* RenderLayerCompositor::rootContentLayer() const
1889{
1890    return m_rootContentLayer.get();
1891}
1892
1893#if ENABLE(RUBBER_BANDING)
1894GraphicsLayer* RenderLayerCompositor::headerLayer() const
1895{
1896    return m_layerForHeader.get();
1897}
1898
1899GraphicsLayer* RenderLayerCompositor::footerLayer() const
1900{
1901    return m_layerForFooter.get();
1902}
1903#endif
1904
1905void RenderLayerCompositor::setIsInWindowForLayerIncludingDescendants(RenderLayer& layer, bool isInWindow)
1906{
1907    if (layer.isComposited() && layer.backing()->usingTiledBacking())
1908        layer.backing()->tiledBacking()->setIsInWindow(isInWindow);
1909
1910    // No need to recurse if we don't have any other tiled layers.
1911    if (hasNonMainLayersWithTiledBacking())
1912        return;
1913
1914    for (RenderLayer* childLayer = layer.firstChild(); childLayer; childLayer = childLayer->nextSibling())
1915        setIsInWindowForLayerIncludingDescendants(*childLayer, isInWindow);
1916}
1917
1918void RenderLayerCompositor::setIsInWindow(bool isInWindow)
1919{
1920    setIsInWindowForLayerIncludingDescendants(*m_renderView.layer(), isInWindow);
1921
1922    if (!inCompositingMode())
1923        return;
1924
1925    if (isInWindow) {
1926        if (m_rootLayerAttachment != RootLayerUnattached)
1927            return;
1928
1929        RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
1930        attachRootLayer(attachment);
1931#if PLATFORM(IOS)
1932        registerAllViewportConstrainedLayers();
1933        registerAllScrollingLayers();
1934#endif
1935    } else {
1936        if (m_rootLayerAttachment == RootLayerUnattached)
1937            return;
1938
1939        detachRootLayer();
1940#if PLATFORM(IOS)
1941        unregisterAllViewportConstrainedLayers();
1942        unregisterAllScrollingLayers();
1943#endif
1944    }
1945}
1946
1947void RenderLayerCompositor::clearBackingForLayerIncludingDescendants(RenderLayer& layer)
1948{
1949    if (layer.isComposited()) {
1950        removeFromScrollCoordinatedLayers(layer);
1951        layer.clearBacking();
1952    }
1953
1954    for (RenderLayer* childLayer = layer.firstChild(); childLayer; childLayer = childLayer->nextSibling())
1955        clearBackingForLayerIncludingDescendants(*childLayer);
1956}
1957
1958void RenderLayerCompositor::clearBackingForAllLayers()
1959{
1960    clearBackingForLayerIncludingDescendants(*m_renderView.layer());
1961}
1962
1963void RenderLayerCompositor::updateRootLayerPosition()
1964{
1965    if (m_rootContentLayer) {
1966        const IntRect& documentRect = m_renderView.documentRect();
1967        m_rootContentLayer->setSize(documentRect.size());
1968        m_rootContentLayer->setPosition(FloatPoint(documentRect.x(), documentRect.y()
1969            + FrameView::yPositionForRootContentLayer(m_renderView.frameView().scrollPosition(), m_renderView.frameView().topContentInset(), m_renderView.frameView().headerHeight())));
1970        m_rootContentLayer->setAnchorPoint(FloatPoint3D());
1971    }
1972    if (m_clipLayer) {
1973        m_clipLayer->setSize(m_renderView.frameView().unscaledVisibleContentSizeIncludingObscuredArea());
1974        m_clipLayer->setPosition(positionForClipLayer());
1975    }
1976
1977#if ENABLE(RUBBER_BANDING)
1978    if (m_contentShadowLayer) {
1979        m_contentShadowLayer->setPosition(m_rootContentLayer->position());
1980        m_contentShadowLayer->setSize(m_rootContentLayer->size());
1981    }
1982
1983    updateLayerForTopOverhangArea(m_layerForTopOverhangArea != nullptr);
1984    updateLayerForBottomOverhangArea(m_layerForBottomOverhangArea != nullptr);
1985    updateLayerForHeader(m_layerForHeader != nullptr);
1986    updateLayerForFooter(m_layerForFooter != nullptr);
1987#endif
1988}
1989
1990bool RenderLayerCompositor::has3DContent() const
1991{
1992    return layerHas3DContent(rootRenderLayer());
1993}
1994
1995bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view)
1996{
1997#if PLATFORM(MAC)
1998    // frames are only independently composited in Mac pre-WebKit2.
1999    return view->platformWidget();
2000#else
2001    UNUSED_PARAM(view);
2002#endif
2003    return false;
2004}
2005
2006bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame() const
2007{
2008    // Parent document content needs to be able to render on top of a composited frame, so correct behavior
2009    // is to have the parent document become composited too. However, this can cause problems on platforms that
2010    // use native views for frames (like Mac), so disable that behavior on those platforms for now.
2011    HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement();
2012    RenderElement* renderer = ownerElement ? ownerElement->renderer() : 0;
2013
2014    // If we are the top-level frame, don't propagate.
2015    if (!ownerElement)
2016        return false;
2017
2018    if (!allowsIndependentlyCompositedFrames(&m_renderView.frameView()))
2019        return true;
2020
2021    if (!renderer || !renderer->isWidget())
2022        return false;
2023
2024    // On Mac, only propagate compositing if the frame is overlapped in the parent
2025    // document, or the parent is already compositing, or the main frame is scaled.
2026    Page* page = this->page();
2027    if (page && page->pageScaleFactor() != 1)
2028        return true;
2029
2030    RenderWidget* frameRenderer = toRenderWidget(renderer);
2031    if (frameRenderer->widget()) {
2032        ASSERT(frameRenderer->widget()->isFrameView());
2033        FrameView* view = toFrameView(frameRenderer->widget());
2034        if (view->isOverlappedIncludingAncestors() || view->hasCompositingAncestor())
2035            return true;
2036    }
2037
2038    return false;
2039}
2040
2041bool RenderLayerCompositor::needsToBeComposited(const RenderLayer& layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
2042{
2043    if (!canBeComposited(layer))
2044        return false;
2045
2046    return requiresCompositingLayer(layer, viewportConstrainedNotCompositedReason) || layer.mustCompositeForIndirectReasons() || (inCompositingMode() && layer.isRootLayer());
2047}
2048
2049// Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
2050// Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
2051// static
2052bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer& layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
2053{
2054    auto renderer = &layer.renderer();
2055
2056    // The compositing state of a reflection should match that of its reflected layer.
2057    if (layer.isReflection())
2058        renderer = toRenderLayerModelObject(renderer->parent()); // The RenderReplica's parent is the object being reflected.
2059
2060    // The root layer always has a compositing layer, but it may not have backing.
2061    return requiresCompositingForTransform(*renderer)
2062        || requiresCompositingForVideo(*renderer)
2063        || requiresCompositingForCanvas(*renderer)
2064        || requiresCompositingForPlugin(*renderer)
2065        || requiresCompositingForFrame(*renderer)
2066        || requiresCompositingForBackfaceVisibility(*renderer)
2067        || clipsCompositingDescendants(*renderer->layer())
2068        || requiresCompositingForAnimation(*renderer)
2069        || requiresCompositingForFilters(*renderer)
2070        || requiresCompositingForPosition(*renderer, *renderer->layer(), viewportConstrainedNotCompositedReason)
2071#if PLATFORM(IOS)
2072        || requiresCompositingForScrolling(*renderer->layer())
2073#endif
2074        || requiresCompositingForOverflowScrolling(*renderer->layer());
2075}
2076
2077bool RenderLayerCompositor::canBeComposited(const RenderLayer& layer) const
2078{
2079    if (m_hasAcceleratedCompositing && layer.isSelfPaintingLayer()) {
2080        if (!layer.isInsideFlowThread())
2081            return true;
2082
2083        // CSS Regions flow threads do not need to be composited as we use composited RenderRegions
2084        // to render the background of the RenderFlowThread.
2085        if (layer.isRenderFlowThread())
2086            return false;
2087
2088        return true;
2089    }
2090    return false;
2091}
2092
2093bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer& layer, const RenderLayer* compositingAncestorLayer, const LayoutRect& layerCompositedBoundsInAncestor, const LayoutRect& ancestorCompositedBounds) const
2094{
2095    auto& renderer = layer.renderer();
2096
2097    if (compositingAncestorLayer
2098        && !(compositingAncestorLayer->backing()->graphicsLayer()->drawsContent()
2099            || compositingAncestorLayer->backing()->paintsIntoWindow()
2100            || compositingAncestorLayer->backing()->paintsIntoCompositedAncestor()))
2101        return true;
2102
2103    if (layer.isRootLayer()
2104        || layer.transform() // note: excludes perspective and transformStyle3D.
2105        || requiresCompositingForVideo(renderer)
2106        || requiresCompositingForCanvas(renderer)
2107        || requiresCompositingForPlugin(renderer)
2108        || requiresCompositingForFrame(renderer)
2109        || requiresCompositingForBackfaceVisibility(renderer)
2110        || requiresCompositingForAnimation(renderer)
2111        || requiresCompositingForFilters(renderer)
2112        || requiresCompositingForPosition(renderer, layer)
2113        || requiresCompositingForOverflowScrolling(layer)
2114        || renderer.isTransparent()
2115        || renderer.hasMask()
2116        || renderer.hasReflection()
2117        || renderer.hasFilter()
2118#if PLATFORM(IOS)
2119        || requiresCompositingForScrolling(layer)
2120#endif
2121        )
2122        return true;
2123
2124
2125    if (layer.mustCompositeForIndirectReasons()) {
2126        RenderLayer::IndirectCompositingReason reason = layer.indirectCompositingReason();
2127        return reason == RenderLayer::IndirectCompositingReason::Overlap
2128            || reason == RenderLayer::IndirectCompositingReason::Stacking
2129            || reason == RenderLayer::IndirectCompositingReason::BackgroundLayer
2130            || reason == RenderLayer::IndirectCompositingReason::GraphicalEffect
2131            || reason == RenderLayer::IndirectCompositingReason::Preserve3D; // preserve-3d has to create backing store to ensure that 3d-transformed elements intersect.
2132    }
2133
2134    if (!ancestorCompositedBounds.contains(layerCompositedBoundsInAncestor))
2135        return true;
2136
2137    return false;
2138}
2139
2140CompositingReasons RenderLayerCompositor::reasonsForCompositing(const RenderLayer& layer) const
2141{
2142    CompositingReasons reasons = CompositingReasonNone;
2143
2144    if (!layer.isComposited())
2145        return reasons;
2146
2147    auto renderer = &layer.renderer();
2148    if (layer.isReflection())
2149        renderer = toRenderLayerModelObject(renderer->parent());
2150
2151    if (requiresCompositingForTransform(*renderer))
2152        reasons |= CompositingReason3DTransform;
2153
2154    if (requiresCompositingForVideo(*renderer))
2155        reasons |= CompositingReasonVideo;
2156    else if (requiresCompositingForCanvas(*renderer))
2157        reasons |= CompositingReasonCanvas;
2158    else if (requiresCompositingForPlugin(*renderer))
2159        reasons |= CompositingReasonPlugin;
2160    else if (requiresCompositingForFrame(*renderer))
2161        reasons |= CompositingReasonIFrame;
2162
2163    if ((canRender3DTransforms() && renderer->style().backfaceVisibility() == BackfaceVisibilityHidden))
2164        reasons |= CompositingReasonBackfaceVisibilityHidden;
2165
2166    if (clipsCompositingDescendants(*renderer->layer()))
2167        reasons |= CompositingReasonClipsCompositingDescendants;
2168
2169    if (requiresCompositingForAnimation(*renderer))
2170        reasons |= CompositingReasonAnimation;
2171
2172    if (requiresCompositingForFilters(*renderer))
2173        reasons |= CompositingReasonFilters;
2174
2175    if (requiresCompositingForPosition(*renderer, *renderer->layer()))
2176        reasons |= renderer->style().position() == FixedPosition ? CompositingReasonPositionFixed : CompositingReasonPositionSticky;
2177
2178#if PLATFORM(IOS)
2179    if (requiresCompositingForScrolling(*renderer->layer()))
2180        reasons |= CompositingReasonOverflowScrollingTouch;
2181#endif
2182
2183    if (requiresCompositingForOverflowScrolling(*renderer->layer()))
2184        reasons |= CompositingReasonOverflowScrollingTouch;
2185
2186    switch (renderer->layer()->indirectCompositingReason()) {
2187    case RenderLayer::IndirectCompositingReason::None:
2188        break;
2189    case RenderLayer::IndirectCompositingReason::Stacking:
2190        reasons |= CompositingReasonStacking;
2191        break;
2192    case RenderLayer::IndirectCompositingReason::Overlap:
2193        reasons |= CompositingReasonOverlap;
2194        break;
2195    case RenderLayer::IndirectCompositingReason::BackgroundLayer:
2196        reasons |= CompositingReasonNegativeZIndexChildren;
2197        break;
2198    case RenderLayer::IndirectCompositingReason::GraphicalEffect:
2199        if (renderer->layer()->transform())
2200            reasons |= CompositingReasonTransformWithCompositedDescendants;
2201
2202        if (renderer->isTransparent())
2203            reasons |= CompositingReasonOpacityWithCompositedDescendants;
2204
2205        if (renderer->hasMask())
2206            reasons |= CompositingReasonMaskWithCompositedDescendants;
2207
2208        if (renderer->hasReflection())
2209            reasons |= CompositingReasonReflectionWithCompositedDescendants;
2210
2211        if (renderer->hasFilter())
2212            reasons |= CompositingReasonFilterWithCompositedDescendants;
2213
2214#if ENABLE(CSS_COMPOSITING)
2215        if (layer.isolatesCompositedBlending())
2216            reasons |= CompositingReasonIsolatesCompositedBlendingDescendants;
2217
2218        if (layer.hasBlendMode())
2219            reasons |= CompositingReasonBlendingWithCompositedDescendants;
2220#endif
2221        break;
2222    case RenderLayer::IndirectCompositingReason::Perspective:
2223        reasons |= CompositingReasonPerspective;
2224        break;
2225    case RenderLayer::IndirectCompositingReason::Preserve3D:
2226        reasons |= CompositingReasonPreserve3D;
2227        break;
2228    }
2229
2230    if (inCompositingMode() && renderer->layer()->isRootLayer())
2231        reasons |= CompositingReasonRoot;
2232
2233    return reasons;
2234}
2235
2236#if !LOG_DISABLED
2237const char* RenderLayerCompositor::logReasonsForCompositing(const RenderLayer& layer)
2238{
2239    CompositingReasons reasons = reasonsForCompositing(layer);
2240
2241    if (reasons & CompositingReason3DTransform)
2242        return "3D transform";
2243
2244    if (reasons & CompositingReasonVideo)
2245        return "video";
2246    else if (reasons & CompositingReasonCanvas)
2247        return "canvas";
2248    else if (reasons & CompositingReasonPlugin)
2249        return "plugin";
2250    else if (reasons & CompositingReasonIFrame)
2251        return "iframe";
2252
2253    if (reasons & CompositingReasonBackfaceVisibilityHidden)
2254        return "backface-visibility: hidden";
2255
2256    if (reasons & CompositingReasonClipsCompositingDescendants)
2257        return "clips compositing descendants";
2258
2259    if (reasons & CompositingReasonAnimation)
2260        return "animation";
2261
2262    if (reasons & CompositingReasonFilters)
2263        return "filters";
2264
2265    if (reasons & CompositingReasonPositionFixed)
2266        return "position: fixed";
2267
2268    if (reasons & CompositingReasonPositionSticky)
2269        return "position: sticky";
2270
2271    if (reasons & CompositingReasonOverflowScrollingTouch)
2272        return "-webkit-overflow-scrolling: touch";
2273
2274    if (reasons & CompositingReasonStacking)
2275        return "stacking";
2276
2277    if (reasons & CompositingReasonOverlap)
2278        return "overlap";
2279
2280    if (reasons & CompositingReasonNegativeZIndexChildren)
2281        return "negative z-index children";
2282
2283    if (reasons & CompositingReasonTransformWithCompositedDescendants)
2284        return "transform with composited descendants";
2285
2286    if (reasons & CompositingReasonOpacityWithCompositedDescendants)
2287        return "opacity with composited descendants";
2288
2289    if (reasons & CompositingReasonMaskWithCompositedDescendants)
2290        return "mask with composited descendants";
2291
2292    if (reasons & CompositingReasonReflectionWithCompositedDescendants)
2293        return "reflection with composited descendants";
2294
2295    if (reasons & CompositingReasonFilterWithCompositedDescendants)
2296        return "filter with composited descendants";
2297
2298#if ENABLE(CSS_COMPOSITING)
2299    if (reasons & CompositingReasonBlendingWithCompositedDescendants)
2300        return "blending with composited descendants";
2301
2302    if (reasons & CompositingReasonIsolatesCompositedBlendingDescendants)
2303        return "isolates composited blending descendants";
2304#endif
2305
2306    if (reasons & CompositingReasonPerspective)
2307        return "perspective";
2308
2309    if (reasons & CompositingReasonPreserve3D)
2310        return "preserve-3d";
2311
2312    if (reasons & CompositingReasonRoot)
2313        return "root";
2314
2315    return "";
2316}
2317#endif
2318
2319// Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
2320// up to the enclosing compositing ancestor. This is required because compositing layers are parented
2321// according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
2322// Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
2323// but a sibling in the z-order hierarchy.
2324bool RenderLayerCompositor::clippedByAncestor(RenderLayer& layer) const
2325{
2326    if (!layer.isComposited() || !layer.parent())
2327        return false;
2328
2329    RenderLayer* compositingAncestor = layer.ancestorCompositingLayer();
2330    if (!compositingAncestor)
2331        return false;
2332
2333    // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
2334    // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
2335    // and layer. The exception is when the compositingAncestor isolates composited blending children,
2336    // in this case it is not allowed to clipsCompositingDescendants() and each of its children
2337    // will be clippedByAncestor()s, including the compositingAncestor.
2338    RenderLayer* computeClipRoot = compositingAncestor;
2339    if (!compositingAncestor->isolatesCompositedBlending()) {
2340        computeClipRoot = nullptr;
2341        RenderLayer* parent = &layer;
2342        while (parent) {
2343            RenderLayer* next = parent->parent();
2344            if (next == compositingAncestor) {
2345                computeClipRoot = parent;
2346                break;
2347            }
2348            parent = next;
2349        }
2350
2351        if (!computeClipRoot || computeClipRoot == &layer)
2352            return false;
2353    }
2354
2355    return layer.backgroundClipRect(RenderLayer::ClipRectsContext(computeClipRoot, TemporaryClipRects)).rect() != LayoutRect::infiniteRect(); // FIXME: Incorrect for CSS regions.
2356}
2357
2358// Return true if the given layer is a stacking context and has compositing child
2359// layers that it needs to clip. In this case we insert a clipping GraphicsLayer
2360// into the hierarchy between this layer and its children in the z-order hierarchy.
2361bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer& layer) const
2362{
2363    return layer.hasCompositingDescendant() && layer.renderer().hasClipOrOverflowClip() && !layer.isolatesCompositedBlending();
2364}
2365
2366bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const
2367{
2368    // Need this done first to determine overflow.
2369    ASSERT(!m_renderView.needsLayout());
2370    HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement();
2371    if (!ownerElement)
2372        return false;
2373
2374    if (!(m_compositingTriggers & ChromeClient::ScrollableInnerFrameTrigger))
2375        return false;
2376
2377    return m_renderView.frameView().isScrollable();
2378}
2379
2380bool RenderLayerCompositor::requiresCompositingForTransform(RenderLayerModelObject& renderer) const
2381{
2382    if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
2383        return false;
2384
2385    // Note that we ask the renderer if it has a transform, because the style may have transforms,
2386    // but the renderer may be an inline that doesn't suppport them.
2387    return renderer.hasTransform() && renderer.style().transform().has3DOperation();
2388}
2389
2390bool RenderLayerCompositor::requiresCompositingForBackfaceVisibility(RenderLayerModelObject& renderer) const
2391{
2392    if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
2393        return false;
2394
2395    if (renderer.style().backfaceVisibility() != BackfaceVisibilityHidden)
2396        return false;
2397
2398    if (renderer.layer()->has3DTransformedAncestor())
2399        return true;
2400
2401    // FIXME: workaround for webkit.org/b/132801
2402    RenderLayer* stackingContext = renderer.layer()->stackingContainer();
2403    if (stackingContext && stackingContext->renderer().style().transformStyle3D() == TransformStyle3DPreserve3D)
2404        return true;
2405
2406    return false;
2407}
2408
2409bool RenderLayerCompositor::requiresCompositingForVideo(RenderLayerModelObject& renderer) const
2410{
2411    if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
2412        return false;
2413#if ENABLE(VIDEO)
2414    if (renderer.isVideo()) {
2415        RenderVideo& video = toRenderVideo(renderer);
2416        return (video.requiresImmediateCompositing() || video.shouldDisplayVideo()) && canAccelerateVideoRendering(video);
2417    }
2418#else
2419    UNUSED_PARAM(renderer);
2420#endif
2421    return false;
2422}
2423
2424bool RenderLayerCompositor::requiresCompositingForCanvas(RenderLayerModelObject& renderer) const
2425{
2426    if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
2427        return false;
2428
2429    if (renderer.isCanvas()) {
2430#if USE(COMPOSITING_FOR_SMALL_CANVASES)
2431        bool isCanvasLargeEnoughToForceCompositing = true;
2432#else
2433        HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer.element());
2434        bool isCanvasLargeEnoughToForceCompositing = canvas->size().area() >= canvasAreaThresholdRequiringCompositing;
2435#endif
2436        CanvasCompositingStrategy compositingStrategy = canvasCompositingStrategy(renderer);
2437        return compositingStrategy == CanvasAsLayerContents || (compositingStrategy == CanvasPaintedToLayer && isCanvasLargeEnoughToForceCompositing);
2438    }
2439
2440    return false;
2441}
2442
2443bool RenderLayerCompositor::requiresCompositingForPlugin(RenderLayerModelObject& renderer) const
2444{
2445    if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
2446        return false;
2447
2448    bool composite = renderer.isEmbeddedObject() && toRenderEmbeddedObject(&renderer)->allowsAcceleratedCompositing();
2449    if (!composite)
2450        return false;
2451
2452    m_reevaluateCompositingAfterLayout = true;
2453
2454    RenderWidget& pluginRenderer = *toRenderWidget(&renderer);
2455    // If we can't reliably know the size of the plugin yet, don't change compositing state.
2456    if (pluginRenderer.needsLayout())
2457        return pluginRenderer.hasLayer() && pluginRenderer.layer()->isComposited();
2458
2459    // Don't go into compositing mode if height or width are zero, or size is 1x1.
2460    IntRect contentBox = pixelSnappedIntRect(pluginRenderer.contentBoxRect());
2461    return contentBox.height() * contentBox.width() > 1;
2462}
2463
2464bool RenderLayerCompositor::requiresCompositingForFrame(RenderLayerModelObject& renderer) const
2465{
2466    if (!renderer.isWidget())
2467        return false;
2468
2469    RenderWidget& frameRenderer = *toRenderWidget(&renderer);
2470
2471    if (!frameRenderer.requiresAcceleratedCompositing())
2472        return false;
2473
2474    m_reevaluateCompositingAfterLayout = true;
2475
2476    RenderLayerCompositor* innerCompositor = frameContentsCompositor(&frameRenderer);
2477    if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame())
2478        return false;
2479
2480    // If we can't reliably know the size of the iframe yet, don't change compositing state.
2481    if (!frameRenderer.parent() || frameRenderer.needsLayout())
2482        return frameRenderer.hasLayer() && frameRenderer.layer()->isComposited();
2483
2484    // Don't go into compositing mode if height or width are zero.
2485    return !pixelSnappedIntRect(frameRenderer.contentBoxRect()).isEmpty();
2486}
2487
2488bool RenderLayerCompositor::requiresCompositingForAnimation(RenderLayerModelObject& renderer) const
2489{
2490    if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
2491        return false;
2492
2493    const AnimationBase::RunningState activeAnimationState = AnimationBase::Running | AnimationBase::Paused | AnimationBase::FillingFowards;
2494    AnimationController& animController = renderer.animation();
2495    return (animController.isRunningAnimationOnRenderer(&renderer, CSSPropertyOpacity, activeAnimationState)
2496            && (inCompositingMode() || (m_compositingTriggers & ChromeClient::AnimatedOpacityTrigger)))
2497#if ENABLE(CSS_FILTERS)
2498            || animController.isRunningAnimationOnRenderer(&renderer, CSSPropertyWebkitFilter, activeAnimationState)
2499#endif // CSS_FILTERS
2500            || animController.isRunningAnimationOnRenderer(&renderer, CSSPropertyWebkitTransform, activeAnimationState);
2501}
2502
2503bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderLayerModelObject& renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason& reason) const
2504{
2505    RenderLayer& layer = *toRenderBoxModelObject(renderer).layer();
2506
2507    // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
2508    // via compositing so that they also apply to those composited descendants.
2509    if (hasCompositedDescendants && (layer.isolatesCompositedBlending() || layer.transform() || renderer.createsGroup() || renderer.hasReflection() || renderer.isRenderNamedFlowFragmentContainer())) {
2510        reason = RenderLayer::IndirectCompositingReason::GraphicalEffect;
2511        return true;
2512    }
2513
2514    // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that
2515    // will be affected by the preserve-3d or perspective.
2516    if (has3DTransformedDescendants) {
2517        if (renderer.style().transformStyle3D() == TransformStyle3DPreserve3D) {
2518            reason = RenderLayer::IndirectCompositingReason::Preserve3D;
2519            return true;
2520        }
2521
2522        if (renderer.style().hasPerspective()) {
2523            reason = RenderLayer::IndirectCompositingReason::Perspective;
2524            return true;
2525        }
2526    }
2527
2528    reason = RenderLayer::IndirectCompositingReason::None;
2529    return false;
2530}
2531
2532bool RenderLayerCompositor::requiresCompositingForFilters(RenderLayerModelObject& renderer) const
2533{
2534#if ENABLE(CSS_FILTERS)
2535    if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
2536        return false;
2537
2538    return renderer.hasFilter();
2539#else
2540    UNUSED_PARAM(renderer);
2541    return false;
2542#endif
2543}
2544
2545bool RenderLayerCompositor::isAsyncScrollableStickyLayer(const RenderLayer& layer, const RenderLayer** enclosingAcceleratedOverflowLayer) const
2546{
2547    ASSERT(layer.renderer().isStickyPositioned());
2548
2549    RenderLayer* enclosingOverflowLayer = layer.enclosingOverflowClipLayer(ExcludeSelf);
2550
2551#if PLATFORM(IOS)
2552    if (enclosingOverflowLayer && enclosingOverflowLayer->hasTouchScrollableOverflow()) {
2553        if (enclosingAcceleratedOverflowLayer)
2554            *enclosingAcceleratedOverflowLayer = enclosingOverflowLayer;
2555        return true;
2556    }
2557#else
2558    UNUSED_PARAM(enclosingAcceleratedOverflowLayer);
2559#endif
2560    // If the layer is inside normal overflow, it's not async-scrollable.
2561    if (enclosingOverflowLayer)
2562        return false;
2563
2564    // No overflow ancestor, so see if the frame supports async scrolling.
2565    if (hasCoordinatedScrolling())
2566        return true;
2567
2568#if PLATFORM(IOS)
2569    // iOS WK1 has fixed/sticky support in the main frame via WebFixedPositionContent.
2570    return m_renderView.frameView().frame().isMainFrame();
2571#else
2572    return false;
2573#endif
2574}
2575
2576bool RenderLayerCompositor::isViewportConstrainedFixedOrStickyLayer(const RenderLayer& layer) const
2577{
2578    if (layer.renderer().isStickyPositioned())
2579        return isAsyncScrollableStickyLayer(layer);
2580
2581    if (layer.renderer().style().position() != FixedPosition)
2582        return false;
2583
2584    // FIXME: Handle fixed inside of a transform, which should not behave as fixed.
2585    for (RenderLayer* stackingContainer = layer.stackingContainer(); stackingContainer; stackingContainer = stackingContainer->stackingContainer()) {
2586        if (stackingContainer->isComposited() && stackingContainer->renderer().style().position() == FixedPosition)
2587            return false;
2588    }
2589
2590    return true;
2591}
2592
2593static bool useCoordinatedScrollingForLayer(RenderView& view, const RenderLayer& layer)
2594{
2595    if (layer.isRootLayer() && view.frameView().frame().isMainFrame())
2596        return true;
2597
2598#if PLATFORM(IOS)
2599    return layer.hasTouchScrollableOverflow();
2600#else
2601    return layer.needsCompositedScrolling();
2602#endif
2603}
2604
2605bool RenderLayerCompositor::requiresCompositingForPosition(RenderLayerModelObject& renderer, const RenderLayer& layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
2606{
2607    // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
2608    // opacity, transform) can get their own composited layer. A stacking context is required otherwise
2609    // z-index and clipping will be broken.
2610    if (!renderer.isPositioned())
2611        return false;
2612
2613    EPosition position = renderer.style().position();
2614    bool isFixed = renderer.isOutOfFlowPositioned() && position == FixedPosition;
2615    if (isFixed && !layer.isStackingContainer())
2616        return false;
2617
2618    bool isSticky = renderer.isInFlowPositioned() && position == StickyPosition;
2619    if (!isFixed && !isSticky)
2620        return false;
2621
2622    // FIXME: acceleratedCompositingForFixedPositionEnabled should probably be renamed acceleratedCompositingForViewportConstrainedPositionEnabled().
2623    const Settings& settings = m_renderView.frameView().frame().settings();
2624    if (!settings.acceleratedCompositingForFixedPositionEnabled())
2625        return false;
2626
2627    if (isSticky)
2628        return isAsyncScrollableStickyLayer(layer);
2629
2630    auto container = renderer.container();
2631    // If the renderer is not hooked up yet then we have to wait until it is.
2632    if (!container) {
2633        m_reevaluateCompositingAfterLayout = true;
2634        return false;
2635    }
2636
2637    // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements.
2638    // They will stay fixed wrt the container rather than the enclosing frame.
2639    if (container != &m_renderView && !renderer.fixedPositionedWithNamedFlowContainingBlock()) {
2640        if (viewportConstrainedNotCompositedReason)
2641            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNonViewContainer;
2642        return false;
2643    }
2644
2645    // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done.
2646    if (!m_inPostLayoutUpdate) {
2647        m_reevaluateCompositingAfterLayout = true;
2648        return layer.isComposited();
2649    }
2650
2651    bool paintsContent = layer.isVisuallyNonEmpty() || layer.hasVisibleDescendant();
2652    if (!paintsContent) {
2653        if (viewportConstrainedNotCompositedReason)
2654            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNoVisibleContent;
2655        return false;
2656    }
2657
2658    // Fixed position elements that are invisible in the current view don't get their own layer.
2659    LayoutRect viewBounds = m_renderView.frameView().viewportConstrainedVisibleContentRect();
2660    LayoutRect layerBounds = layer.calculateLayerBounds(&layer, LayoutSize(), RenderLayer::UseLocalClipRectIfPossible | RenderLayer::IncludeLayerFilterOutsets | RenderLayer::UseFragmentBoxesExcludingCompositing
2661        | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask | RenderLayer::IncludeCompositedDescendants);
2662    // Map to m_renderView to ignore page scale.
2663    FloatRect absoluteBounds = layer.renderer().localToContainerQuad(FloatRect(layerBounds), &m_renderView).boundingBox();
2664    if (!viewBounds.intersects(enclosingIntRect(absoluteBounds))) {
2665        if (viewportConstrainedNotCompositedReason)
2666            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView;
2667        return false;
2668    }
2669
2670    return true;
2671}
2672
2673bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const RenderLayer& layer) const
2674{
2675    return layer.needsCompositedScrolling();
2676}
2677
2678#if PLATFORM(IOS)
2679bool RenderLayerCompositor::requiresCompositingForScrolling(const RenderLayer& layer) const
2680{
2681    if (!layer.hasAcceleratedTouchScrolling())
2682        return false;
2683
2684    if (!m_inPostLayoutUpdate) {
2685        m_reevaluateCompositingAfterLayout = true;
2686        return layer.isComposited();
2687    }
2688
2689    return layer.hasTouchScrollableOverflow();
2690}
2691#endif
2692
2693bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderLayerModelObject& renderer) const
2694{
2695    if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
2696        return false;
2697
2698    return renderer.animation().isRunningAcceleratedAnimationOnRenderer(&renderer, CSSPropertyWebkitTransform, AnimationBase::Running | AnimationBase::Paused);
2699}
2700
2701// If an element has negative z-index children, those children render in front of the
2702// layer background, so we need an extra 'contents' layer for the foreground of the layer
2703// object.
2704bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer& layer) const
2705{
2706    return layer.hasNegativeZOrderList();
2707}
2708
2709bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const
2710{
2711    FrameView& frameView = m_renderView.frameView();
2712
2713    // This applies when the application UI handles scrolling, in which case RenderLayerCompositor doesn't need to manage it.
2714    if (frameView.delegatesScrolling() && frameView.frame().isMainFrame())
2715        return false;
2716
2717    // We need to handle our own scrolling if we're:
2718    return !m_renderView.frameView().platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2)
2719        || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac
2720}
2721
2722static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
2723{
2724    if (!scrollbar)
2725        return;
2726
2727    context.save();
2728    const IntRect& scrollbarRect = scrollbar->frameRect();
2729    context.translate(-scrollbarRect.x(), -scrollbarRect.y());
2730    IntRect transformedClip = clip;
2731    transformedClip.moveBy(scrollbarRect.location());
2732    scrollbar->paint(&context, transformedClip);
2733    context.restore();
2734}
2735
2736void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const FloatRect& clip)
2737{
2738    IntRect pixelSnappedRectForIntegralPositionedItems = pixelSnappedIntRect(LayoutRect(clip));
2739    if (graphicsLayer == layerForHorizontalScrollbar())
2740        paintScrollbar(m_renderView.frameView().horizontalScrollbar(), context, pixelSnappedRectForIntegralPositionedItems);
2741    else if (graphicsLayer == layerForVerticalScrollbar())
2742        paintScrollbar(m_renderView.frameView().verticalScrollbar(), context, pixelSnappedRectForIntegralPositionedItems);
2743    else if (graphicsLayer == layerForScrollCorner()) {
2744        const IntRect& scrollCorner = m_renderView.frameView().scrollCornerRect();
2745        context.save();
2746        context.translate(-scrollCorner.x(), -scrollCorner.y());
2747        IntRect transformedClip = pixelSnappedRectForIntegralPositionedItems;
2748        transformedClip.moveBy(scrollCorner.location());
2749        m_renderView.frameView().paintScrollCorner(&context, transformedClip);
2750        context.restore();
2751    }
2752}
2753
2754bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
2755{
2756    RenderLayerBacking* renderViewBacking = m_renderView.layer()->backing();
2757    return renderViewBacking && renderViewBacking->usingTiledBacking();
2758}
2759
2760bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer& layer) const
2761{
2762    if (&layer != m_renderView.layer())
2763        return false;
2764
2765    if (m_renderView.frameView().frame().settings().fixedBackgroundsPaintRelativeToDocument())
2766        return false;
2767
2768    return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgroundIsEntirelyFixed();
2769}
2770
2771GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const
2772{
2773    // Get the fixed root background from the RenderView layer's backing.
2774    RenderLayer* viewLayer = m_renderView.layer();
2775    if (!viewLayer)
2776        return nullptr;
2777
2778    if (viewLayer->isComposited() && viewLayer->backing()->backgroundLayerPaintsFixedRootBackground())
2779        return viewLayer->backing()->backgroundLayer();
2780
2781    return nullptr;
2782}
2783
2784static void resetTrackedRepaintRectsRecursive(GraphicsLayer& graphicsLayer)
2785{
2786    graphicsLayer.resetTrackedRepaints();
2787
2788    for (size_t i = 0, size = graphicsLayer.children().size(); i < size; ++i)
2789        resetTrackedRepaintRectsRecursive(*graphicsLayer.children()[i]);
2790
2791    if (GraphicsLayer* replicaLayer = graphicsLayer.replicaLayer())
2792        resetTrackedRepaintRectsRecursive(*replicaLayer);
2793
2794    if (GraphicsLayer* maskLayer = graphicsLayer.maskLayer())
2795        resetTrackedRepaintRectsRecursive(*maskLayer);
2796}
2797
2798void RenderLayerCompositor::resetTrackedRepaintRects()
2799{
2800    if (GraphicsLayer* rootLayer = rootGraphicsLayer())
2801        resetTrackedRepaintRectsRecursive(*rootLayer);
2802}
2803
2804void RenderLayerCompositor::setTracksRepaints(bool tracksRepaints)
2805{
2806    m_isTrackingRepaints = tracksRepaints;
2807}
2808
2809bool RenderLayerCompositor::isTrackingRepaints() const
2810{
2811    return m_isTrackingRepaints;
2812}
2813
2814float RenderLayerCompositor::deviceScaleFactor() const
2815{
2816    Page* page = this->page();
2817    return page ? page->deviceScaleFactor() : 1;
2818}
2819
2820float RenderLayerCompositor::pageScaleFactor() const
2821{
2822    Page* page = this->page();
2823    return page ? page->pageScaleFactor() : 1;
2824}
2825
2826float RenderLayerCompositor::zoomedOutPageScaleFactor() const
2827{
2828    Page* page = this->page();
2829    return page ? page->zoomedOutPageScaleFactor() : 0;
2830}
2831
2832float RenderLayerCompositor::contentsScaleMultiplierForNewTiles(const GraphicsLayer*) const
2833{
2834#if PLATFORM(IOS)
2835    LegacyTileCache* tileCache = nullptr;
2836    if (Page* page = this->page()) {
2837        if (FrameView* frameView = page->mainFrame().view())
2838            tileCache = frameView->legacyTileCache();
2839    }
2840
2841    if (!tileCache)
2842        return 1;
2843
2844    return tileCache->tileControllerShouldUseLowScaleTiles() ? 0.125 : 1;
2845#else
2846    return 1;
2847#endif
2848}
2849
2850void RenderLayerCompositor::didCommitChangesForLayer(const GraphicsLayer*) const
2851{
2852    // Nothing to do here yet.
2853}
2854
2855bool RenderLayerCompositor::mainFrameBackingIsTiled() const
2856{
2857    RenderLayer* layer = m_renderView.layer();
2858    if (!layer)
2859        return false;
2860
2861    RenderLayerBacking* backing = layer->backing();
2862    if (!backing)
2863        return false;
2864
2865    return backing->usingTiledBacking();
2866}
2867
2868bool RenderLayerCompositor::shouldCompositeOverflowControls() const
2869{
2870    FrameView& frameView = m_renderView.frameView();
2871
2872    if (frameView.platformWidget())
2873        return false;
2874
2875    if (frameView.delegatesScrolling())
2876        return false;
2877
2878    if (mainFrameBackingIsTiled())
2879        return true;
2880
2881    if (!frameView.hasOverlayScrollbars())
2882        return false;
2883
2884    return true;
2885}
2886
2887bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
2888{
2889    return shouldCompositeOverflowControls() && m_renderView.frameView().horizontalScrollbar();
2890}
2891
2892bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
2893{
2894    return shouldCompositeOverflowControls() && m_renderView.frameView().verticalScrollbar();
2895}
2896
2897bool RenderLayerCompositor::requiresScrollCornerLayer() const
2898{
2899    return shouldCompositeOverflowControls() && m_renderView.frameView().isScrollCornerVisible();
2900}
2901
2902#if ENABLE(RUBBER_BANDING)
2903bool RenderLayerCompositor::requiresOverhangAreasLayer() const
2904{
2905    // We don't want a layer if this is a subframe.
2906    if (m_renderView.document().ownerElement())
2907        return false;
2908
2909    // We do want a layer if we're using tiled drawing and can scroll.
2910    if (mainFrameBackingIsTiled() && m_renderView.frameView().hasOpaqueBackground() && !m_renderView.frameView().prohibitsScrolling())
2911        return true;
2912
2913    return false;
2914}
2915
2916bool RenderLayerCompositor::requiresContentShadowLayer() const
2917{
2918    // We don't want a layer if this is a subframe.
2919    if (m_renderView.document().ownerElement())
2920        return false;
2921
2922#if PLATFORM(COCOA)
2923    if (viewHasTransparentBackground())
2924        return false;
2925
2926    // If the background is going to extend, then it doesn't make sense to have a shadow layer.
2927    if (m_renderView.frameView().frame().settings().backgroundShouldExtendBeyondPage())
2928        return false;
2929
2930    // On Mac, we want a content shadow layer if we're using tiled drawing and can scroll.
2931    if (mainFrameBackingIsTiled() && !m_renderView.frameView().prohibitsScrolling())
2932        return true;
2933#endif
2934
2935    return false;
2936}
2937
2938GraphicsLayer* RenderLayerCompositor::updateLayerForTopOverhangArea(bool wantsLayer)
2939{
2940    if (m_renderView.document().ownerElement())
2941        return 0;
2942
2943    if (!wantsLayer) {
2944        if (m_layerForTopOverhangArea) {
2945            m_layerForTopOverhangArea->removeFromParent();
2946            m_layerForTopOverhangArea = nullptr;
2947        }
2948        return 0;
2949    }
2950
2951    if (!m_layerForTopOverhangArea) {
2952        m_layerForTopOverhangArea = GraphicsLayer::create(graphicsLayerFactory(), *this);
2953#ifndef NDEBUG
2954        m_layerForTopOverhangArea->setName("top overhang area");
2955#endif
2956        m_scrollLayer->addChildBelow(m_layerForTopOverhangArea.get(), m_rootContentLayer.get());
2957    }
2958
2959    return m_layerForTopOverhangArea.get();
2960}
2961
2962GraphicsLayer* RenderLayerCompositor::updateLayerForBottomOverhangArea(bool wantsLayer)
2963{
2964    if (m_renderView.document().ownerElement())
2965        return 0;
2966
2967    if (!wantsLayer) {
2968        if (m_layerForBottomOverhangArea) {
2969            m_layerForBottomOverhangArea->removeFromParent();
2970            m_layerForBottomOverhangArea = nullptr;
2971        }
2972        return 0;
2973    }
2974
2975    if (!m_layerForBottomOverhangArea) {
2976        m_layerForBottomOverhangArea = GraphicsLayer::create(graphicsLayerFactory(), *this);
2977#ifndef NDEBUG
2978        m_layerForBottomOverhangArea->setName("bottom overhang area");
2979#endif
2980        m_scrollLayer->addChildBelow(m_layerForBottomOverhangArea.get(), m_rootContentLayer.get());
2981    }
2982
2983    m_layerForBottomOverhangArea->setPosition(FloatPoint(0, m_rootContentLayer->size().height() + m_renderView.frameView().headerHeight()
2984        + m_renderView.frameView().footerHeight() + m_renderView.frameView().topContentInset()));
2985    return m_layerForBottomOverhangArea.get();
2986}
2987
2988GraphicsLayer* RenderLayerCompositor::updateLayerForHeader(bool wantsLayer)
2989{
2990    if (m_renderView.document().ownerElement())
2991        return 0;
2992
2993    if (!wantsLayer) {
2994        if (m_layerForHeader) {
2995            m_layerForHeader->removeFromParent();
2996            m_layerForHeader = nullptr;
2997
2998            // The ScrollingTree knows about the header layer, and the position of the root layer is affected
2999            // by the header layer, so if we remove the header, we need to tell the scrolling tree.
3000            if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
3001                scrollingCoordinator->frameViewRootLayerDidChange(&m_renderView.frameView());
3002        }
3003        return 0;
3004    }
3005
3006    if (!m_layerForHeader) {
3007        m_layerForHeader = GraphicsLayer::create(graphicsLayerFactory(), *this);
3008#ifndef NDEBUG
3009        m_layerForHeader->setName("header");
3010#endif
3011        m_scrollLayer->addChildAbove(m_layerForHeader.get(), m_rootContentLayer.get());
3012        m_renderView.frameView().addPaintPendingMilestones(DidFirstFlushForHeaderLayer);
3013    }
3014
3015    m_layerForHeader->setPosition(FloatPoint(0,
3016        FrameView::yPositionForHeaderLayer(m_renderView.frameView().scrollPosition(), m_renderView.frameView().topContentInset())));
3017    m_layerForHeader->setAnchorPoint(FloatPoint3D());
3018    m_layerForHeader->setSize(FloatSize(m_renderView.frameView().visibleWidth(), m_renderView.frameView().headerHeight()));
3019
3020    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
3021        scrollingCoordinator->frameViewRootLayerDidChange(&m_renderView.frameView());
3022
3023    if (Page* page = this->page())
3024        page->chrome().client().didAddHeaderLayer(m_layerForHeader.get());
3025
3026    return m_layerForHeader.get();
3027}
3028
3029GraphicsLayer* RenderLayerCompositor::updateLayerForFooter(bool wantsLayer)
3030{
3031    if (m_renderView.document().ownerElement())
3032        return 0;
3033
3034    if (!wantsLayer) {
3035        if (m_layerForFooter) {
3036            m_layerForFooter->removeFromParent();
3037            m_layerForFooter = nullptr;
3038
3039            // The ScrollingTree knows about the footer layer, and the total scrollable size is affected
3040            // by the footer layer, so if we remove the footer, we need to tell the scrolling tree.
3041            if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
3042                scrollingCoordinator->frameViewRootLayerDidChange(&m_renderView.frameView());
3043        }
3044        return 0;
3045    }
3046
3047    if (!m_layerForFooter) {
3048        m_layerForFooter = GraphicsLayer::create(graphicsLayerFactory(), *this);
3049#ifndef NDEBUG
3050        m_layerForFooter->setName("footer");
3051#endif
3052        m_scrollLayer->addChildAbove(m_layerForFooter.get(), m_rootContentLayer.get());
3053    }
3054
3055    float totalContentHeight = m_rootContentLayer->size().height() + m_renderView.frameView().headerHeight() + m_renderView.frameView().footerHeight();
3056    m_layerForFooter->setPosition(FloatPoint(0, FrameView::yPositionForFooterLayer(m_renderView.frameView().scrollPosition(),
3057        m_renderView.frameView().topContentInset(), totalContentHeight, m_renderView.frameView().footerHeight())));
3058    m_layerForFooter->setAnchorPoint(FloatPoint3D());
3059    m_layerForFooter->setSize(FloatSize(m_renderView.frameView().visibleWidth(), m_renderView.frameView().footerHeight()));
3060
3061    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
3062        scrollingCoordinator->frameViewRootLayerDidChange(&m_renderView.frameView());
3063
3064    if (Page* page = this->page())
3065        page->chrome().client().didAddFooterLayer(m_layerForFooter.get());
3066
3067    return m_layerForFooter.get();
3068}
3069
3070#endif
3071
3072bool RenderLayerCompositor::viewHasTransparentBackground(Color* backgroundColor) const
3073{
3074    if (m_renderView.frameView().isTransparent()) {
3075        if (backgroundColor)
3076            *backgroundColor = Color(); // Return an invalid color.
3077        return true;
3078    }
3079
3080    Color documentBackgroundColor = m_renderView.frameView().documentBackgroundColor();
3081    if (!documentBackgroundColor.isValid())
3082        documentBackgroundColor = Color::white;
3083
3084    if (backgroundColor)
3085        *backgroundColor = documentBackgroundColor;
3086
3087    return documentBackgroundColor.hasAlpha();
3088}
3089
3090void RenderLayerCompositor::setRootExtendedBackgroundColor(const Color& color)
3091{
3092    if (color == m_rootExtendedBackgroundColor)
3093        return;
3094
3095    m_rootExtendedBackgroundColor = color;
3096
3097    if (Page* page = this->page())
3098        page->chrome().client().pageExtendedBackgroundColorDidChange(color);
3099
3100#if ENABLE(RUBBER_BANDING)
3101    if (!m_layerForOverhangAreas)
3102        return;
3103
3104    m_layerForOverhangAreas->setBackgroundColor(m_rootExtendedBackgroundColor);
3105
3106    if (!m_rootExtendedBackgroundColor.isValid())
3107        m_layerForOverhangAreas->setCustomAppearance(GraphicsLayer::ScrollingOverhang);
3108#endif
3109}
3110
3111void RenderLayerCompositor::updateOverflowControlsLayers()
3112{
3113#if ENABLE(RUBBER_BANDING)
3114    if (requiresOverhangAreasLayer()) {
3115        if (!m_layerForOverhangAreas) {
3116            m_layerForOverhangAreas = GraphicsLayer::create(graphicsLayerFactory(), *this);
3117#ifndef NDEBUG
3118            m_layerForOverhangAreas->setName("overhang areas");
3119#endif
3120            m_layerForOverhangAreas->setDrawsContent(false);
3121
3122            float topContentInset = m_renderView.frameView().topContentInset();
3123            IntSize overhangAreaSize = m_renderView.frameView().frameRect().size();
3124            overhangAreaSize.setHeight(overhangAreaSize.height() - topContentInset);
3125            m_layerForOverhangAreas->setSize(overhangAreaSize);
3126            m_layerForOverhangAreas->setPosition(FloatPoint(0, topContentInset));
3127            m_layerForOverhangAreas->setAnchorPoint(FloatPoint3D());
3128
3129            if (m_renderView.frameView().frame().settings().backgroundShouldExtendBeyondPage())
3130                m_layerForOverhangAreas->setBackgroundColor(m_renderView.frameView().documentBackgroundColor());
3131            else
3132                m_layerForOverhangAreas->setCustomAppearance(GraphicsLayer::ScrollingOverhang);
3133
3134            // We want the overhang areas layer to be positioned below the frame contents,
3135            // so insert it below the clip layer.
3136            m_overflowControlsHostLayer->addChildBelow(m_layerForOverhangAreas.get(), m_clipLayer.get());
3137        }
3138    } else if (m_layerForOverhangAreas) {
3139        m_layerForOverhangAreas->removeFromParent();
3140        m_layerForOverhangAreas = nullptr;
3141    }
3142
3143    if (requiresContentShadowLayer()) {
3144        if (!m_contentShadowLayer) {
3145            m_contentShadowLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
3146#ifndef NDEBUG
3147            m_contentShadowLayer->setName("content shadow");
3148#endif
3149            m_contentShadowLayer->setSize(m_rootContentLayer->size());
3150            m_contentShadowLayer->setPosition(m_rootContentLayer->position());
3151            m_contentShadowLayer->setAnchorPoint(FloatPoint3D());
3152            m_contentShadowLayer->setCustomAppearance(GraphicsLayer::ScrollingShadow);
3153
3154            m_scrollLayer->addChildBelow(m_contentShadowLayer.get(), m_rootContentLayer.get());
3155        }
3156    } else if (m_contentShadowLayer) {
3157        m_contentShadowLayer->removeFromParent();
3158        m_contentShadowLayer = nullptr;
3159    }
3160#endif
3161
3162    if (requiresHorizontalScrollbarLayer()) {
3163        if (!m_layerForHorizontalScrollbar) {
3164            m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), *this);
3165            m_layerForHorizontalScrollbar->setShowDebugBorder(m_showDebugBorders);
3166#ifndef NDEBUG
3167            m_layerForHorizontalScrollbar->setName("horizontal scrollbar container");
3168
3169#endif
3170#if PLATFORM(COCOA) && USE(CA)
3171            m_layerForHorizontalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
3172#endif
3173            m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
3174
3175            if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
3176                scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_renderView.frameView(), HorizontalScrollbar);
3177        }
3178    } else if (m_layerForHorizontalScrollbar) {
3179        m_layerForHorizontalScrollbar->removeFromParent();
3180        m_layerForHorizontalScrollbar = nullptr;
3181
3182        if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
3183            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_renderView.frameView(), HorizontalScrollbar);
3184    }
3185
3186    if (requiresVerticalScrollbarLayer()) {
3187        if (!m_layerForVerticalScrollbar) {
3188            m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), *this);
3189            m_layerForVerticalScrollbar->setShowDebugBorder(m_showDebugBorders);
3190#ifndef NDEBUG
3191            m_layerForVerticalScrollbar->setName("vertical scrollbar container");
3192#endif
3193#if PLATFORM(COCOA) && USE(CA)
3194            m_layerForVerticalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
3195#endif
3196            m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
3197
3198            if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
3199                scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_renderView.frameView(), VerticalScrollbar);
3200        }
3201    } else if (m_layerForVerticalScrollbar) {
3202        m_layerForVerticalScrollbar->removeFromParent();
3203        m_layerForVerticalScrollbar = nullptr;
3204
3205        if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
3206            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_renderView.frameView(), VerticalScrollbar);
3207    }
3208
3209    if (requiresScrollCornerLayer()) {
3210        if (!m_layerForScrollCorner) {
3211            m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), *this);
3212            m_layerForScrollCorner->setShowDebugBorder(m_showDebugBorders);
3213#ifndef NDEBUG
3214            m_layerForScrollCorner->setName("scroll corner");
3215#endif
3216#if PLATFORM(COCOA) && USE(CA)
3217            m_layerForScrollCorner->setAcceleratesDrawing(acceleratedDrawingEnabled());
3218#endif
3219            m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
3220        }
3221    } else if (m_layerForScrollCorner) {
3222        m_layerForScrollCorner->removeFromParent();
3223        m_layerForScrollCorner = nullptr;
3224    }
3225
3226    m_renderView.frameView().positionScrollbarLayers();
3227}
3228
3229void RenderLayerCompositor::ensureRootLayer()
3230{
3231    RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;
3232    if (expectedAttachment == m_rootLayerAttachment)
3233         return;
3234
3235    if (!m_rootContentLayer) {
3236        m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
3237#ifndef NDEBUG
3238        m_rootContentLayer->setName("content root");
3239#endif
3240        IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect();
3241        m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
3242        m_rootContentLayer->setPosition(FloatPoint());
3243
3244#if PLATFORM(IOS) || PLATFORM(EFL)
3245        // Page scale is applied above this on iOS, so we'll just say that our root layer applies it.
3246        Frame& frame = m_renderView.frameView().frame();
3247        if (frame.isMainFrame())
3248            m_rootContentLayer->setAppliesPageScale();
3249#endif
3250
3251        // Need to clip to prevent transformed content showing outside this frame
3252        m_rootContentLayer->setMasksToBounds(true);
3253    }
3254
3255    if (requiresScrollLayer(expectedAttachment)) {
3256        if (!m_overflowControlsHostLayer) {
3257            ASSERT(!m_scrollLayer);
3258            ASSERT(!m_clipLayer);
3259
3260            // Create a layer to host the clipping layer and the overflow controls layers.
3261            m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
3262#ifndef NDEBUG
3263            m_overflowControlsHostLayer->setName("overflow controls host");
3264#endif
3265
3266            // Create a clipping layer if this is an iframe
3267            m_clipLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
3268#ifndef NDEBUG
3269            m_clipLayer->setName("frame clipping");
3270#endif
3271            m_clipLayer->setMasksToBounds(true);
3272
3273            m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
3274#ifndef NDEBUG
3275            m_scrollLayer->setName("frame scrolling");
3276#endif
3277            // Hook them up
3278            m_overflowControlsHostLayer->addChild(m_clipLayer.get());
3279            m_clipLayer->addChild(m_scrollLayer.get());
3280            m_scrollLayer->addChild(m_rootContentLayer.get());
3281
3282            m_clipLayer->setSize(m_renderView.frameView().unscaledVisibleContentSizeIncludingObscuredArea());
3283            m_clipLayer->setPosition(positionForClipLayer());
3284            m_clipLayer->setAnchorPoint(FloatPoint3D());
3285
3286            updateOverflowControlsLayers();
3287
3288            if (hasCoordinatedScrolling())
3289                scheduleLayerFlush(true);
3290            else
3291                updateScrollLayerPosition();
3292        }
3293    } else {
3294        if (m_overflowControlsHostLayer) {
3295            m_overflowControlsHostLayer = nullptr;
3296            m_clipLayer = nullptr;
3297            m_scrollLayer = nullptr;
3298        }
3299    }
3300
3301    // Check to see if we have to change the attachment
3302    if (m_rootLayerAttachment != RootLayerUnattached)
3303        detachRootLayer();
3304
3305    attachRootLayer(expectedAttachment);
3306}
3307
3308void RenderLayerCompositor::destroyRootLayer()
3309{
3310    if (!m_rootContentLayer)
3311        return;
3312
3313    detachRootLayer();
3314
3315#if ENABLE(RUBBER_BANDING)
3316    if (m_layerForOverhangAreas) {
3317        m_layerForOverhangAreas->removeFromParent();
3318        m_layerForOverhangAreas = nullptr;
3319    }
3320#endif
3321
3322    if (m_layerForHorizontalScrollbar) {
3323        m_layerForHorizontalScrollbar->removeFromParent();
3324        m_layerForHorizontalScrollbar = nullptr;
3325        if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
3326            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_renderView.frameView(), HorizontalScrollbar);
3327        if (Scrollbar* horizontalScrollbar = m_renderView.frameView().verticalScrollbar())
3328            m_renderView.frameView().invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
3329    }
3330
3331    if (m_layerForVerticalScrollbar) {
3332        m_layerForVerticalScrollbar->removeFromParent();
3333        m_layerForVerticalScrollbar = nullptr;
3334        if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
3335            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(&m_renderView.frameView(), VerticalScrollbar);
3336        if (Scrollbar* verticalScrollbar = m_renderView.frameView().verticalScrollbar())
3337            m_renderView.frameView().invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
3338    }
3339
3340    if (m_layerForScrollCorner) {
3341        m_layerForScrollCorner = nullptr;
3342        m_renderView.frameView().invalidateScrollCorner(m_renderView.frameView().scrollCornerRect());
3343    }
3344
3345    if (m_overflowControlsHostLayer) {
3346        m_overflowControlsHostLayer = nullptr;
3347        m_clipLayer = nullptr;
3348        m_scrollLayer = nullptr;
3349    }
3350    ASSERT(!m_scrollLayer);
3351    m_rootContentLayer = nullptr;
3352
3353    m_layerUpdater = nullptr;
3354}
3355
3356void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
3357{
3358    if (!m_rootContentLayer)
3359        return;
3360
3361    switch (attachment) {
3362        case RootLayerUnattached:
3363            ASSERT_NOT_REACHED();
3364            break;
3365        case RootLayerAttachedViaChromeClient: {
3366            Frame& frame = m_renderView.frameView().frame();
3367            Page* page = frame.page();
3368            if (!page)
3369                return;
3370
3371            page->chrome().client().attachRootGraphicsLayer(&frame, rootGraphicsLayer());
3372            break;
3373        }
3374        case RootLayerAttachedViaEnclosingFrame: {
3375            // The layer will get hooked up via RenderLayerBacking::updateConfiguration()
3376            // for the frame's renderer in the parent document.
3377            m_renderView.document().ownerElement()->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
3378            break;
3379        }
3380    }
3381
3382    m_rootLayerAttachment = attachment;
3383    rootLayerAttachmentChanged();
3384
3385    if (m_shouldFlushOnReattach) {
3386        scheduleLayerFlushNow();
3387        m_shouldFlushOnReattach = false;
3388    }
3389}
3390
3391void RenderLayerCompositor::detachRootLayer()
3392{
3393    if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
3394        return;
3395
3396    switch (m_rootLayerAttachment) {
3397    case RootLayerAttachedViaEnclosingFrame: {
3398        // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
3399        // for the frame's renderer in the parent document.
3400        if (m_overflowControlsHostLayer)
3401            m_overflowControlsHostLayer->removeFromParent();
3402        else
3403            m_rootContentLayer->removeFromParent();
3404
3405        if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement())
3406            ownerElement->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
3407        break;
3408    }
3409    case RootLayerAttachedViaChromeClient: {
3410        Frame& frame = m_renderView.frameView().frame();
3411        Page* page = frame.page();
3412        if (!page)
3413            return;
3414
3415        page->chrome().client().attachRootGraphicsLayer(&frame, 0);
3416    }
3417    break;
3418    case RootLayerUnattached:
3419        break;
3420    }
3421
3422    m_rootLayerAttachment = RootLayerUnattached;
3423    rootLayerAttachmentChanged();
3424}
3425
3426void RenderLayerCompositor::updateRootLayerAttachment()
3427{
3428    ensureRootLayer();
3429}
3430
3431void RenderLayerCompositor::rootLayerAttachmentChanged()
3432{
3433    // The attachment can affect whether the RenderView layer's paintsIntoWindow() behavior,
3434    // so call updateDrawsContent() to update that.
3435    RenderLayer* layer = m_renderView.layer();
3436    if (RenderLayerBacking* backing = layer ? layer->backing() : 0)
3437        backing->updateDrawsContent();
3438
3439    // The document-relative page overlay layer (which is pinned to the main frame's layer tree)
3440    // is moved between different RenderLayerCompositors' layer trees, and needs to be
3441    // reattached whenever we swap in a new RenderLayerCompositor.
3442    if (m_rootLayerAttachment == RootLayerUnattached)
3443        return;
3444
3445    Frame& frame = m_renderView.frameView().frame();
3446    Page* page = frame.page();
3447    if (!page)
3448        return;
3449
3450    if (GraphicsLayer* overlayLayer = page->chrome().client().documentOverlayLayerForFrame(frame))
3451        m_rootContentLayer->addChild(overlayLayer);
3452}
3453
3454// IFrames are special, because we hook compositing layers together across iframe boundaries
3455// when both parent and iframe content are composited. So when this frame becomes composited, we have
3456// to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
3457void RenderLayerCompositor::notifyIFramesOfCompositingChange()
3458{
3459    Frame& frame = m_renderView.frameView().frame();
3460    for (Frame* child = frame.tree().firstChild(); child; child = child->tree().traverseNext(&frame)) {
3461        if (child->document() && child->document()->ownerElement())
3462            child->document()->ownerElement()->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
3463    }
3464
3465    // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
3466    // we need to schedule a style recalc in our parent document.
3467    if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement())
3468        ownerElement->scheduleSetNeedsStyleRecalc(SyntheticStyleChange);
3469}
3470
3471bool RenderLayerCompositor::layerHas3DContent(const RenderLayer& layer) const
3472{
3473    const RenderStyle& style = layer.renderer().style();
3474
3475    if (style.transformStyle3D() == TransformStyle3DPreserve3D || style.hasPerspective() || style.transform().has3DOperation())
3476        return true;
3477
3478    const_cast<RenderLayer&>(layer).updateLayerListsIfNeeded();
3479
3480#if !ASSERT_DISABLED
3481    LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(&layer));
3482#endif
3483
3484    if (layer.isStackingContainer()) {
3485        if (Vector<RenderLayer*>* negZOrderList = layer.negZOrderList()) {
3486            for (size_t i = 0, size = negZOrderList->size(); i < size; ++i) {
3487                if (layerHas3DContent(*negZOrderList->at(i)))
3488                    return true;
3489            }
3490        }
3491
3492        if (Vector<RenderLayer*>* posZOrderList = layer.posZOrderList()) {
3493            for (size_t i = 0, size = posZOrderList->size(); i < size; ++i) {
3494                if (layerHas3DContent(*posZOrderList->at(i)))
3495                    return true;
3496            }
3497        }
3498    }
3499
3500    if (Vector<RenderLayer*>* normalFlowList = layer.normalFlowList()) {
3501        for (size_t i = 0, size = normalFlowList->size(); i < size; ++i) {
3502            if (layerHas3DContent(*normalFlowList->at(i)))
3503                return true;
3504        }
3505    }
3506
3507    return false;
3508}
3509
3510void RenderLayerCompositor::deviceOrPageScaleFactorChanged()
3511{
3512    // Page scale will only be applied at to the RenderView and sublayers, but the device scale factor
3513    // needs to be applied at the level of rootGraphicsLayer().
3514    GraphicsLayer* rootLayer = rootGraphicsLayer();
3515    if (rootLayer)
3516        rootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
3517}
3518
3519void RenderLayerCompositor::updateScrollCoordinatedStatus(RenderLayer& layer)
3520{
3521    ScrollCoordinationReasons coordinationReasons = 0;
3522    if (isViewportConstrainedFixedOrStickyLayer(layer))
3523        coordinationReasons |= FixedOrSticky;
3524
3525    if (useCoordinatedScrollingForLayer(m_renderView, layer))
3526        coordinationReasons |= Scrolling;
3527
3528    if (coordinationReasons) {
3529        if (m_scrollCoordinatedLayers.add(&layer).isNewEntry)
3530            m_subframeScrollLayersNeedReattach = true;
3531
3532        updateScrollCoordinatedLayer(layer, coordinationReasons);
3533    } else
3534        removeFromScrollCoordinatedLayers(layer);
3535}
3536
3537void RenderLayerCompositor::removeFromScrollCoordinatedLayers(RenderLayer& layer)
3538{
3539    if (!m_scrollCoordinatedLayers.contains(&layer))
3540        return;
3541
3542    m_subframeScrollLayersNeedReattach = true;
3543
3544    m_scrollCoordinatedLayers.remove(&layer);
3545    m_scrollCoordinatedLayersNeedingUpdate.remove(&layer);
3546
3547    detachScrollCoordinatedLayer(layer);
3548}
3549
3550FixedPositionViewportConstraints RenderLayerCompositor::computeFixedViewportConstraints(RenderLayer& layer) const
3551{
3552    ASSERT(layer.isComposited());
3553
3554    GraphicsLayer* graphicsLayer = layer.backing()->graphicsLayer();
3555    LayoutRect viewportRect = m_renderView.frameView().viewportConstrainedVisibleContentRect();
3556
3557    FixedPositionViewportConstraints constraints;
3558    constraints.setLayerPositionAtLastLayout(graphicsLayer->position());
3559    constraints.setViewportRectAtLastLayout(viewportRect);
3560    constraints.setAlignmentOffset(graphicsLayer->pixelAlignmentOffset());
3561
3562    const RenderStyle& style = layer.renderer().style();
3563    if (!style.left().isAuto())
3564        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
3565
3566    if (!style.right().isAuto())
3567        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight);
3568
3569    if (!style.top().isAuto())
3570        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
3571
3572    if (!style.bottom().isAuto())
3573        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom);
3574
3575    // If left and right are auto, use left.
3576    if (style.left().isAuto() && style.right().isAuto())
3577        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
3578
3579    // If top and bottom are auto, use top.
3580    if (style.top().isAuto() && style.bottom().isAuto())
3581        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
3582
3583    return constraints;
3584}
3585
3586StickyPositionViewportConstraints RenderLayerCompositor::computeStickyViewportConstraints(RenderLayer& layer) const
3587{
3588    ASSERT(layer.isComposited());
3589#if !PLATFORM(IOS)
3590    // We should never get here for stickies constrained by an enclosing clipping layer.
3591    // FIXME: Why does this assertion fail on iOS?
3592    ASSERT(!layer.enclosingOverflowClipLayer(ExcludeSelf));
3593#endif
3594
3595    RenderBoxModelObject& renderer = toRenderBoxModelObject(layer.renderer());
3596
3597    StickyPositionViewportConstraints constraints;
3598    renderer.computeStickyPositionConstraints(constraints, renderer.constrainingRectForStickyPosition());
3599
3600    GraphicsLayer* graphicsLayer = layer.backing()->graphicsLayer();
3601
3602    constraints.setLayerPositionAtLastLayout(graphicsLayer->position());
3603    constraints.setStickyOffsetAtLastLayout(renderer.stickyPositionOffset());
3604    constraints.setAlignmentOffset(graphicsLayer->pixelAlignmentOffset());
3605
3606    return constraints;
3607}
3608
3609static ScrollingNodeID enclosingScrollingNodeID(RenderLayer& layer, IncludeSelfOrNot includeSelf)
3610{
3611    RenderLayer* currLayer = includeSelf == IncludeSelf ? &layer : layer.parent();
3612    while (currLayer) {
3613        if (RenderLayerBacking* backing = currLayer->backing()) {
3614            if (ScrollingNodeID nodeID = backing->scrollingNodeIDForChildren())
3615                return nodeID;
3616        }
3617        currLayer = currLayer->parent();
3618    }
3619
3620    return 0;
3621}
3622
3623static ScrollingNodeID scrollCoordinatedAncestorInParentOfFrame(Frame& frame)
3624{
3625    if (!frame.document() || !frame.view())
3626        return 0;
3627
3628    // Find the frame's enclosing layer in our render tree.
3629    HTMLFrameOwnerElement* ownerElement = frame.document()->ownerElement();
3630    RenderElement* frameRenderer = ownerElement ? ownerElement->renderer() : nullptr;
3631    if (!frameRenderer)
3632        return 0;
3633
3634    RenderLayer* layerInParentDocument = frameRenderer->enclosingLayer();
3635    if (!layerInParentDocument)
3636        return 0;
3637
3638    return enclosingScrollingNodeID(*layerInParentDocument, IncludeSelf);
3639}
3640
3641void RenderLayerCompositor::reattachSubframeScrollLayers()
3642{
3643    if (!m_subframeScrollLayersNeedReattach)
3644        return;
3645
3646    m_subframeScrollLayersNeedReattach = false;
3647
3648    ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator();
3649
3650    for (Frame* child = m_renderView.frameView().frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
3651        if (!child->document() || !child->view())
3652            continue;
3653
3654        // Ignore frames that are not scroll-coordinated.
3655        FrameView* childFrameView = child->view();
3656        ScrollingNodeID frameScrollingNodeID = childFrameView->scrollLayerID();
3657        if (!frameScrollingNodeID)
3658            continue;
3659
3660        ScrollingNodeID parentNodeID = scrollCoordinatedAncestorInParentOfFrame(*child);
3661        if (!parentNodeID)
3662            continue;
3663
3664        scrollingCoordinator->attachToStateTree(FrameScrollingNode, frameScrollingNodeID, parentNodeID);
3665    }
3666}
3667
3668ScrollingNodeID RenderLayerCompositor::attachScrollingNode(RenderLayer& layer, ScrollingNodeType nodeType, ScrollingNodeID parentNodeID)
3669{
3670    ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator();
3671    RenderLayerBacking* backing = layer.backing();
3672
3673    ScrollingNodeID nodeID = backing->scrollingNodeIDForRole(nodeType);
3674    if (!nodeID)
3675        nodeID = scrollingCoordinator->uniqueScrollLayerID();
3676
3677    nodeID = scrollingCoordinator->attachToStateTree(nodeType, nodeID, parentNodeID);
3678    if (!nodeID)
3679        return 0;
3680
3681    backing->setScrollingNodeIDForRole(nodeID, nodeType);
3682    m_scrollingNodeToLayerMap.add(nodeID, &layer);
3683
3684    return nodeID;
3685}
3686
3687void RenderLayerCompositor::updateScrollCoordinationForThisFrame(ScrollingNodeID parentNodeID)
3688{
3689    ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator();
3690    ASSERT(scrollingCoordinator->coordinatesScrollingForFrameView(&m_renderView.frameView()));
3691
3692    ScrollingNodeID nodeID = attachScrollingNode(*m_renderView.layer(), FrameScrollingNode, parentNodeID);
3693    scrollingCoordinator->updateFrameScrollingNode(nodeID, m_scrollLayer.get(), m_rootContentLayer.get(), fixedRootBackgroundLayer(), clipLayer());
3694}
3695
3696void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, ScrollCoordinationReasons reasons)
3697{
3698    ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator();
3699    if (!scrollingCoordinator || !scrollingCoordinator->coordinatesScrollingForFrameView(&m_renderView.frameView()))
3700        return;
3701
3702    bool isRootLayer = &layer == m_renderView.layer();
3703
3704    // FIXME: Remove supportsFixedPositionLayers() since all platforms support them now.
3705    if (!scrollingCoordinator->supportsFixedPositionLayers() || (!layer.parent() && !isRootLayer))
3706        return;
3707
3708    ASSERT(m_scrollCoordinatedLayers.contains(&layer));
3709    ASSERT(layer.isComposited());
3710
3711    RenderLayerBacking* backing = layer.backing();
3712    if (!backing)
3713        return;
3714
3715    if (!m_renderView.frame().isMainFrame()) {
3716        ScrollingNodeID parentDocumentHostingNodeID = scrollCoordinatedAncestorInParentOfFrame(m_renderView.frame());
3717        if (!parentDocumentHostingNodeID)
3718            return;
3719
3720        updateScrollCoordinationForThisFrame(parentDocumentHostingNodeID);
3721        if (!(reasons & FixedOrSticky) && isRootLayer)
3722            return;
3723    }
3724
3725    ScrollingNodeID parentNodeID = enclosingScrollingNodeID(layer, ExcludeSelf);
3726    if (!parentNodeID && !isRootLayer)
3727        return;
3728
3729    // Always call this even if the backing is already attached because the parent may have changed.
3730    // If a node plays both roles, fixed/sticky is always the ancestor node of scrolling.
3731    if (reasons & FixedOrSticky) {
3732        ScrollingNodeType nodeType = FrameScrollingNode;
3733        if (layer.renderer().style().position() == FixedPosition)
3734            nodeType = FixedNode;
3735        else if (layer.renderer().style().position() == StickyPosition)
3736            nodeType = StickyNode;
3737        else
3738            ASSERT_NOT_REACHED();
3739
3740        ScrollingNodeID nodeID = attachScrollingNode(layer, nodeType, parentNodeID);
3741        if (!nodeID)
3742            return;
3743
3744        switch (nodeType) {
3745        case FixedNode:
3746            scrollingCoordinator->updateViewportConstrainedNode(nodeID, computeFixedViewportConstraints(layer), backing->graphicsLayer());
3747            break;
3748        case StickyNode:
3749            scrollingCoordinator->updateViewportConstrainedNode(nodeID, computeStickyViewportConstraints(layer), backing->graphicsLayer());
3750            break;
3751        case FrameScrollingNode:
3752        case OverflowScrollingNode:
3753            break;
3754        }
3755
3756        parentNodeID = nodeID;
3757    }
3758
3759    if (reasons & Scrolling) {
3760        if (isRootLayer)
3761            updateScrollCoordinationForThisFrame(parentNodeID);
3762        else {
3763            ScrollingNodeType nodeType = OverflowScrollingNode;
3764            ScrollingNodeID nodeID = attachScrollingNode(layer, nodeType, parentNodeID);
3765            if (!nodeID)
3766                return;
3767
3768            ScrollingCoordinator::ScrollingGeometry scrollingGeometry;
3769            scrollingGeometry.scrollOrigin = layer.scrollOrigin();
3770            scrollingGeometry.scrollPosition = layer.scrollPosition();
3771            scrollingGeometry.scrollableAreaSize = layer.visibleSize();
3772            scrollingGeometry.contentSize = layer.contentsSize();
3773            scrollingGeometry.reachableContentSize = layer.scrollableContentsSize();
3774            scrollingCoordinator->updateOverflowScrollingNode(nodeID, backing->scrollingLayer(), backing->scrollingContentsLayer(), &scrollingGeometry);
3775        }
3776    }
3777}
3778
3779void RenderLayerCompositor::detachScrollCoordinatedLayer(RenderLayer& layer)
3780{
3781    RenderLayerBacking* backing = layer.backing();
3782    if (!backing)
3783        return;
3784
3785    if (ScrollingNodeID nodeID = backing->scrollingNodeIDForRole(FrameScrollingNode))
3786        m_scrollingNodeToLayerMap.remove(nodeID);
3787
3788    if (ScrollingNodeID nodeID = backing->scrollingNodeIDForRole(FixedNode))
3789        m_scrollingNodeToLayerMap.remove(nodeID);
3790
3791    backing->detachFromScrollingCoordinator();
3792}
3793
3794ScrollableArea* RenderLayerCompositor::scrollableAreaForScrollLayerID(ScrollingNodeID nodeID) const
3795{
3796    if (!nodeID)
3797        return nullptr;
3798
3799    return m_scrollingNodeToLayerMap.get(nodeID);
3800}
3801
3802#if PLATFORM(IOS)
3803typedef HashMap<PlatformLayer*, std::unique_ptr<ViewportConstraints>> LayerMap;
3804typedef HashMap<PlatformLayer*, PlatformLayer*> StickyContainerMap;
3805
3806void RenderLayerCompositor::registerAllViewportConstrainedLayers()
3807{
3808    // Only the main frame should register fixed/sticky layers.
3809    if (m_renderView.document().ownerElement())
3810        return;
3811
3812    if (scrollingCoordinator())
3813        return;
3814
3815    LayerMap layerMap;
3816    StickyContainerMap stickyContainerMap;
3817
3818    for (auto it = m_scrollCoordinatedLayers.begin(), end = m_scrollCoordinatedLayers.end(); it != end; ++it) {
3819        RenderLayer& layer = **it;
3820        ASSERT(layer.isComposited());
3821
3822        std::unique_ptr<ViewportConstraints> constraints;
3823        if (layer.renderer().isStickyPositioned()) {
3824            constraints = std::make_unique<StickyPositionViewportConstraints>(computeStickyViewportConstraints(layer));
3825            const RenderLayer* enclosingTouchScrollableLayer = nullptr;
3826            if (isAsyncScrollableStickyLayer(layer, &enclosingTouchScrollableLayer) && enclosingTouchScrollableLayer) {
3827                ASSERT(enclosingTouchScrollableLayer->isComposited());
3828                stickyContainerMap.add(layer.backing()->graphicsLayer()->platformLayer(), enclosingTouchScrollableLayer->backing()->scrollingLayer()->platformLayer());
3829            }
3830        } else if (layer.renderer().style().position() == FixedPosition)
3831            constraints = std::make_unique<FixedPositionViewportConstraints>(computeFixedViewportConstraints(layer));
3832        else
3833            continue;
3834
3835        layerMap.add(layer.backing()->graphicsLayer()->platformLayer(), WTF::move(constraints));
3836    }
3837
3838    if (ChromeClient* client = this->chromeClient())
3839        client->updateViewportConstrainedLayers(layerMap, stickyContainerMap);
3840}
3841
3842void RenderLayerCompositor::unregisterAllViewportConstrainedLayers()
3843{
3844    // Only the main frame should register fixed/sticky layers.
3845    if (m_renderView.document().ownerElement())
3846        return;
3847
3848    if (scrollingCoordinator())
3849        return;
3850
3851    if (ChromeClient* client = this->chromeClient()) {
3852        LayerMap layerMap;
3853        StickyContainerMap stickyContainerMap;
3854        client->updateViewportConstrainedLayers(layerMap, stickyContainerMap);
3855    }
3856}
3857
3858void RenderLayerCompositor::registerAllScrollingLayers()
3859{
3860    ChromeClient* client = this->chromeClient();
3861    if (!client)
3862        return;
3863
3864    for (auto it = m_scrollingLayers.begin(), end = m_scrollingLayers.end(); it != end; ++it)
3865        updateScrollingLayerWithClient(**it, client);
3866}
3867
3868void RenderLayerCompositor::unregisterAllScrollingLayers()
3869{
3870    ChromeClient* client = this->chromeClient();
3871    if (!client)
3872        return;
3873
3874    for (auto it = m_scrollingLayers.begin(), end = m_scrollingLayers.end(); it != end; ++it) {
3875        RenderLayer& layer = **it;
3876        RenderLayerBacking* backing = layer.backing();
3877        ASSERT(backing);
3878        client->removeScrollingLayer(layer.renderer().element(), backing->scrollingLayer()->platformLayer(), backing->scrollingContentsLayer()->platformLayer());
3879    }
3880}
3881#endif
3882
3883void RenderLayerCompositor::willRemoveScrollingLayerWithBacking(RenderLayer& layer, RenderLayerBacking& backing)
3884{
3885    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
3886        backing.detachFromScrollingCoordinator();
3887
3888        // For Coordinated Graphics.
3889        scrollingCoordinator->scrollableAreaScrollLayerDidChange(&layer);
3890        return;
3891    }
3892
3893#if PLATFORM(IOS)
3894    m_scrollingLayersNeedingUpdate.remove(&layer);
3895    m_scrollingLayers.remove(&layer);
3896
3897    if (m_renderView.document().inPageCache())
3898        return;
3899
3900    if (ChromeClient* client = this->chromeClient()) {
3901        PlatformLayer* scrollingLayer = backing.scrollingLayer()->platformLayer();
3902        PlatformLayer* contentsLayer = backing.scrollingContentsLayer()->platformLayer();
3903        client->removeScrollingLayer(layer.renderer().element(), scrollingLayer, contentsLayer);
3904    }
3905#endif
3906}
3907
3908void RenderLayerCompositor::didAddScrollingLayer(RenderLayer& layer)
3909{
3910    updateScrollCoordinatedStatus(layer);
3911
3912    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
3913        // For Coordinated Graphics.
3914        scrollingCoordinator->scrollableAreaScrollLayerDidChange(&layer);
3915        return;
3916    }
3917
3918#if PLATFORM(IOS)
3919    ASSERT(!m_renderView.document().inPageCache());
3920    m_scrollingLayers.add(&layer);
3921#endif
3922}
3923
3924void RenderLayerCompositor::windowScreenDidChange(PlatformDisplayID displayID)
3925{
3926    if (m_layerUpdater)
3927        m_layerUpdater->screenDidChange(displayID);
3928}
3929
3930ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
3931{
3932    if (Page* page = this->page())
3933        return page->scrollingCoordinator();
3934
3935    return 0;
3936}
3937
3938GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
3939{
3940    if (Page* page = this->page())
3941        return page->chrome().client().graphicsLayerFactory();
3942
3943    return 0;
3944}
3945
3946Page* RenderLayerCompositor::page() const
3947{
3948    return m_renderView.frameView().frame().page();
3949}
3950
3951void RenderLayerCompositor::setLayerFlushThrottlingEnabled(bool enabled)
3952{
3953    m_layerFlushThrottlingEnabled = enabled;
3954    if (m_layerFlushThrottlingEnabled)
3955        return;
3956    m_layerFlushTimer.stop();
3957    if (!m_hasPendingLayerFlush)
3958        return;
3959    scheduleLayerFlushNow();
3960}
3961
3962void RenderLayerCompositor::disableLayerFlushThrottlingTemporarilyForInteraction()
3963{
3964    if (m_layerFlushThrottlingTemporarilyDisabledForInteraction)
3965        return;
3966    m_layerFlushThrottlingTemporarilyDisabledForInteraction = true;
3967}
3968
3969bool RenderLayerCompositor::isThrottlingLayerFlushes() const
3970{
3971    if (!m_layerFlushThrottlingEnabled)
3972        return false;
3973    if (!m_layerFlushTimer.isActive())
3974        return false;
3975    if (m_layerFlushThrottlingTemporarilyDisabledForInteraction)
3976        return false;
3977    return true;
3978}
3979
3980void RenderLayerCompositor::startLayerFlushTimerIfNeeded()
3981{
3982    m_layerFlushThrottlingTemporarilyDisabledForInteraction = false;
3983    m_layerFlushTimer.stop();
3984    if (!m_layerFlushThrottlingEnabled)
3985        return;
3986    m_layerFlushTimer.startOneShot(throttledLayerFlushDelay);
3987}
3988
3989void RenderLayerCompositor::startInitialLayerFlushTimerIfNeeded()
3990{
3991    if (!m_layerFlushThrottlingEnabled)
3992        return;
3993    if (m_layerFlushTimer.isActive())
3994        return;
3995    m_layerFlushTimer.startOneShot(throttledLayerFlushInitialDelay);
3996}
3997
3998void RenderLayerCompositor::layerFlushTimerFired(Timer<RenderLayerCompositor>&)
3999{
4000    if (!m_hasPendingLayerFlush)
4001        return;
4002    scheduleLayerFlushNow();
4003}
4004
4005void RenderLayerCompositor::paintRelatedMilestonesTimerFired(Timer<RenderLayerCompositor>&)
4006{
4007    Frame& frame = m_renderView.frameView().frame();
4008    Page* page = frame.page();
4009    if (!page)
4010        return;
4011
4012    // If the layer tree is frozen, we'll paint when it's unfrozen and schedule the timer again.
4013    if (page->chrome().client().layerTreeStateIsFrozen())
4014        return;
4015
4016    m_renderView.frameView().firePaintRelatedMilestonesIfNeeded();
4017}
4018
4019#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
4020PassRefPtr<DisplayRefreshMonitor> RenderLayerCompositor::createDisplayRefreshMonitor(PlatformDisplayID displayID) const
4021{
4022    Frame& frame = m_renderView.frameView().frame();
4023    Page* page = frame.page();
4024    if (!page)
4025        return nullptr;
4026
4027    return page->chrome().client().createDisplayRefreshMonitor(displayID);
4028}
4029#endif
4030
4031} // namespace WebCore
4032