/*
 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"

#include "RenderLayerCompositor.h"

#include "CSSAnimationController.h"
#include "CSSPropertyNames.h"
#include "CanvasRenderingContext.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "DocumentTimeline.h"
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsLayer.h"
#include "HTMLCanvasElement.h"
#include "HTMLIFrameElement.h"
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "InspectorInstrumentation.h"
#include "Logging.h"
#include "NodeList.h"
#include "Page.h"
#include "PageOverlayController.h"
#include "RenderEmbeddedObject.h"
#include "RenderFragmentedFlow.h"
#include "RenderFullScreen.h"
#include "RenderGeometryMap.h"
#include "RenderIFrame.h"
#include "RenderLayerBacking.h"
#include "RenderReplica.h"
#include "RenderVideo.h"
#include "RenderView.h"
#include "RuntimeEnabledFeatures.h"
#include "ScrollingConstraints.h"
#include "ScrollingCoordinator.h"
#include "Settings.h"
#include "TiledBacking.h"
#include "TransformState.h"
#include <wtf/SetForScope.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/TextStream.h>

#if PLATFORM(IOS)
#include "LegacyTileCache.h"
#include "RenderScrollbar.h"
#endif

#if ENABLE(TREE_DEBUGGING)
#include "RenderTreeAsText.h"
#endif

#if ENABLE(3D_TRANSFORMS)
// This symbol is used to determine from a script whether 3D rendering is enabled (via 'nm').
WEBCORE_EXPORT bool WebCoreHas3DRendering = true;
#endif

#if !PLATFORM(MAC) && !PLATFORM(IOS)
#define USE_COMPOSITING_FOR_SMALL_CANVASES 1
#endif

namespace WebCore {

#if !USE(COMPOSITING_FOR_SMALL_CANVASES)
static const int canvasAreaThresholdRequiringCompositing = 50 * 100;
#endif
// During page loading delay layer flushes up to this many seconds to allow them coalesce, reducing workload.
#if PLATFORM(IOS)
static const Seconds throttledLayerFlushInitialDelay { 500_ms };
static const Seconds throttledLayerFlushDelay { 1.5_s };
#else
static const Seconds throttledLayerFlushInitialDelay { 500_ms };
static const Seconds throttledLayerFlushDelay { 500_ms };
#endif

using namespace HTMLNames;

class OverlapMapContainer {
public:
    void add(const LayoutRect& bounds)
    {
        m_layerRects.append(bounds);
        m_boundingBox.unite(bounds);
    }

    bool overlapsLayers(const LayoutRect& bounds) const
    {
        // Checking with the bounding box will quickly reject cases when
        // layers are created for lists of items going in one direction and
        // never overlap with each other.
        if (!bounds.intersects(m_boundingBox))
            return false;
        for (const auto& layerRect : m_layerRects) {
            if (layerRect.intersects(bounds))
                return true;
        }
        return false;
    }

    void unite(const OverlapMapContainer& otherContainer)
    {
        m_layerRects.appendVector(otherContainer.m_layerRects);
        m_boundingBox.unite(otherContainer.m_boundingBox);
    }
private:
    Vector<LayoutRect> m_layerRects;
    LayoutRect m_boundingBox;
};

class RenderLayerCompositor::OverlapMap {
    WTF_MAKE_NONCOPYABLE(OverlapMap);
public:
    OverlapMap()
        : m_geometryMap(UseTransforms)
    {
        // Begin assuming the root layer will be composited so that there is
        // something on the stack. The root layer should also never get an
        // popCompositingContainer call.
        pushCompositingContainer();
    }

    void add(const LayoutRect& bounds)
    {
        // Layers do not contribute to overlap immediately--instead, they will
        // contribute to overlap as soon as their composited ancestor has been
        // recursively processed and popped off the stack.
        ASSERT(m_overlapStack.size() >= 2);
        m_overlapStack[m_overlapStack.size() - 2].add(bounds);
        m_isEmpty = false;
    }

    bool overlapsLayers(const LayoutRect& bounds) const
    {
        return m_overlapStack.last().overlapsLayers(bounds);
    }

    bool isEmpty() const
    {
        return m_isEmpty;
    }

    void pushCompositingContainer()
    {
        m_overlapStack.append(OverlapMapContainer());
    }

    void popCompositingContainer()
    {
        m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last());
        m_overlapStack.removeLast();
    }

    const RenderGeometryMap& geometryMap() const { return m_geometryMap; }
    RenderGeometryMap& geometryMap() { return m_geometryMap; }

private:
    struct RectList {
        Vector<LayoutRect> rects;
        LayoutRect boundingRect;
        
        void append(const LayoutRect& rect)
        {
            rects.append(rect);
            boundingRect.unite(rect);
        }

        void append(const RectList& rectList)
        {
            rects.appendVector(rectList.rects);
            boundingRect.unite(rectList.boundingRect);
        }
        
        bool intersects(const LayoutRect& rect) const
        {
            if (!rects.size() || !boundingRect.intersects(rect))
                return false;

            for (const auto& currentRect : rects) {
                if (currentRect.intersects(rect))
                    return true;
            }
            return false;
        }
    };

    Vector<OverlapMapContainer> m_overlapStack;
    RenderGeometryMap m_geometryMap;
    bool m_isEmpty { true };
};

struct RenderLayerCompositor::CompositingState {
    CompositingState(RenderLayer* compAncestor, bool testOverlap = true)
        : compositingAncestor(compAncestor)
        , subtreeIsCompositing(false)
        , testingOverlap(testOverlap)
        , ancestorHasTransformAnimation(false)
#if ENABLE(CSS_COMPOSITING)
        , hasNotIsolatedCompositedBlendingDescendants(false)
#endif
#if ENABLE(TREE_DEBUGGING)
        , depth(0)
#endif
    {
    }
    
    CompositingState(const CompositingState& other)
        : compositingAncestor(other.compositingAncestor)
        , subtreeIsCompositing(other.subtreeIsCompositing)
        , testingOverlap(other.testingOverlap)
        , ancestorHasTransformAnimation(other.ancestorHasTransformAnimation)
#if ENABLE(CSS_COMPOSITING)
        , hasNotIsolatedCompositedBlendingDescendants(other.hasNotIsolatedCompositedBlendingDescendants)
#endif
#if ENABLE(TREE_DEBUGGING)
        , depth(other.depth + 1)
#endif
    {
    }
    
    RenderLayer* compositingAncestor;
    bool subtreeIsCompositing;
    bool testingOverlap;
    bool ancestorHasTransformAnimation;
#if ENABLE(CSS_COMPOSITING)
    bool hasNotIsolatedCompositedBlendingDescendants;
#endif
#if ENABLE(TREE_DEBUGGING)
    int depth;
#endif
};

struct RenderLayerCompositor::OverlapExtent {
    LayoutRect bounds;
    bool extentComputed { false };
    bool hasTransformAnimation { false };
    bool animationCausesExtentUncertainty { false };

    bool knownToBeHaveExtentUncertainty() const { return extentComputed && animationCausesExtentUncertainty; }
};

#if !LOG_DISABLED
static inline bool compositingLogEnabled()
{
    return LogCompositing.state == WTFLogChannelOn;
}
#endif

RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView)
    : m_renderView(renderView)
    , m_updateCompositingLayersTimer(*this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
    , m_layerFlushTimer(*this, &RenderLayerCompositor::layerFlushTimerFired)
{
}

RenderLayerCompositor::~RenderLayerCompositor()
{
    // Take care that the owned GraphicsLayers are deleted first as their destructors may call back here.
    m_clipLayer = nullptr;
    m_scrollLayer = nullptr;
    ASSERT(m_rootLayerAttachment == RootLayerUnattached);
}

void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
{
    if (enable != m_compositing) {
        m_compositing = enable;
        
        if (m_compositing) {
            ensureRootLayer();
            notifyIFramesOfCompositingChange();
        } else
            destroyRootLayer();
    }
}

void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
{
    auto& settings = m_renderView.settings();
    bool hasAcceleratedCompositing = settings.acceleratedCompositingEnabled();

    // We allow the chrome to override the settings, in case the page is rendered
    // on a chrome that doesn't allow accelerated compositing.
    if (hasAcceleratedCompositing) {
        m_compositingTriggers = page().chrome().client().allowedCompositingTriggers();
        hasAcceleratedCompositing = m_compositingTriggers;
    }

    bool showDebugBorders = settings.showDebugBorders();
    bool showRepaintCounter = settings.showRepaintCounter();
    bool acceleratedDrawingEnabled = settings.acceleratedDrawingEnabled();
    bool displayListDrawingEnabled = settings.displayListDrawingEnabled();

    // forceCompositingMode for subframes can only be computed after layout.
    bool forceCompositingMode = m_forceCompositingMode;
    if (isMainFrameCompositor())
        forceCompositingMode = m_renderView.settings().forceCompositingMode() && hasAcceleratedCompositing; 
    
    if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode) {
        setCompositingLayersNeedRebuild();
        m_layerNeedsCompositingUpdate = true;
    }

    bool debugBordersChanged = m_showDebugBorders != showDebugBorders;
    m_hasAcceleratedCompositing = hasAcceleratedCompositing;
    m_forceCompositingMode = forceCompositingMode;
    m_showDebugBorders = showDebugBorders;
    m_showRepaintCounter = showRepaintCounter;
    m_acceleratedDrawingEnabled = acceleratedDrawingEnabled;
    m_displayListDrawingEnabled = displayListDrawingEnabled;
    
    if (debugBordersChanged) {
        if (m_layerForHorizontalScrollbar)
            m_layerForHorizontalScrollbar->setShowDebugBorder(m_showDebugBorders);

        if (m_layerForVerticalScrollbar)
            m_layerForVerticalScrollbar->setShowDebugBorder(m_showDebugBorders);

        if (m_layerForScrollCorner)
            m_layerForScrollCorner->setShowDebugBorder(m_showDebugBorders);
    }
}

void RenderLayerCompositor::cacheAcceleratedCompositingFlagsAfterLayout()
{
    cacheAcceleratedCompositingFlags();

    if (isMainFrameCompositor())
        return;

    bool forceCompositingMode = m_hasAcceleratedCompositing && m_renderView.settings().forceCompositingMode() && requiresCompositingForScrollableFrame();
    if (forceCompositingMode != m_forceCompositingMode) {
        m_forceCompositingMode = forceCompositingMode;
        setCompositingLayersNeedRebuild();
    }
}

bool RenderLayerCompositor::canRender3DTransforms() const
{
    return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
}

void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
{
    if (inCompositingMode())
        m_compositingLayersNeedRebuild = needRebuild;
}

void RenderLayerCompositor::willRecalcStyle()
{
    m_layerNeedsCompositingUpdate = false;
    cacheAcceleratedCompositingFlags();
}

bool RenderLayerCompositor::didRecalcStyleWithNoPendingLayout()
{
    if (!m_layerNeedsCompositingUpdate)
        return false;
    
    return updateCompositingLayers(CompositingUpdateType::AfterStyleChange);
}

void RenderLayerCompositor::customPositionForVisibleRectComputation(const GraphicsLayer* graphicsLayer, FloatPoint& position) const
{
    if (graphicsLayer != m_scrollLayer.get())
        return;

    FloatPoint scrollPosition = -position;

    if (m_renderView.frameView().scrollBehaviorForFixedElements() == StickToDocumentBounds)
        scrollPosition = m_renderView.frameView().constrainScrollPositionForOverhang(roundedIntPoint(scrollPosition));

    position = -scrollPosition;
}

void RenderLayerCompositor::notifyFlushRequired(const GraphicsLayer* layer)
{
    scheduleLayerFlush(layer->canThrottleLayerFlush());
}

void RenderLayerCompositor::scheduleLayerFlushNow()
{
    m_hasPendingLayerFlush = false;
    page().chrome().client().scheduleCompositingLayerFlush();
}

void RenderLayerCompositor::scheduleLayerFlush(bool canThrottle)
{
    ASSERT(!m_flushingLayers);

    if (canThrottle)
        startInitialLayerFlushTimerIfNeeded();

    if (canThrottle && isThrottlingLayerFlushes()) {
        m_hasPendingLayerFlush = true;
        return;
    }
    scheduleLayerFlushNow();
}

FloatRect RenderLayerCompositor::visibleRectForLayerFlushing() const
{
    const FrameView& frameView = m_renderView.frameView();
#if PLATFORM(IOS)
    return frameView.exposedContentRect();
#else
    // Having a m_clipLayer indicates that we're doing scrolling via GraphicsLayers.
    FloatRect visibleRect = m_clipLayer ? FloatRect({ }, frameView.sizeForVisibleContent()) : frameView.visibleContentRect();

    if (frameView.viewExposedRect())
        visibleRect.intersect(frameView.viewExposedRect().value());

    return visibleRect;
#endif
}

void RenderLayerCompositor::flushPendingLayerChanges(bool isFlushRoot)
{
    // FrameView::flushCompositingStateIncludingSubframes() flushes each subframe,
    // but GraphicsLayer::flushCompositingState() will cross frame boundaries
    // if the GraphicsLayers are connected (the RootLayerAttachedViaEnclosingFrame case).
    // As long as we're not the root of the flush, we can bail.
    if (!isFlushRoot && rootLayerAttachment() == RootLayerAttachedViaEnclosingFrame)
        return;
    
    if (rootLayerAttachment() == RootLayerUnattached) {
#if PLATFORM(IOS)
        startLayerFlushTimerIfNeeded();
#endif
        m_shouldFlushOnReattach = true;
        return;
    }

    auto& frameView = m_renderView.frameView();
    AnimationUpdateBlock animationUpdateBlock(&frameView.frame().animation());

    ASSERT(!m_flushingLayers);
    m_flushingLayers = true;

    if (auto* rootLayer = rootGraphicsLayer()) {
        FloatRect visibleRect = visibleRectForLayerFlushing();
        LOG_WITH_STREAM(Compositing,  stream << "\nRenderLayerCompositor " << this << " flushPendingLayerChanges (is root " << isFlushRoot << ") visible rect " << visibleRect);
        rootLayer->flushCompositingState(visibleRect);
    }
    
    ASSERT(m_flushingLayers);
    m_flushingLayers = false;

    updateScrollCoordinatedLayersAfterFlushIncludingSubframes();

#if PLATFORM(IOS)
    if (isFlushRoot)
        page().chrome().client().didFlushCompositingLayers();
#endif

    ++m_layerFlushCount;
    startLayerFlushTimerIfNeeded();
}

void RenderLayerCompositor::updateScrollCoordinatedLayersAfterFlushIncludingSubframes()
{
    updateScrollCoordinatedLayersAfterFlush();

    auto& frame = m_renderView.frameView().frame();
    for (Frame* subframe = frame.tree().firstChild(); subframe; subframe = subframe->tree().traverseNext(&frame)) {
        auto* view = subframe->contentRenderer();
        if (!view)
            continue;

        view->compositor().updateScrollCoordinatedLayersAfterFlush();
    }
}

void RenderLayerCompositor::updateScrollCoordinatedLayersAfterFlush()
{
#if PLATFORM(IOS)
    updateCustomLayersAfterFlush();
#endif

    for (auto* layer : m_scrollCoordinatedLayersNeedingUpdate)
        updateScrollCoordinatedStatus(*layer, ScrollingNodeChangeFlags::Layer);

    m_scrollCoordinatedLayersNeedingUpdate.clear();
}

#if PLATFORM(IOS)
static bool scrollbarHasDisplayNone(Scrollbar* scrollbar)
{
    if (!scrollbar || !scrollbar->isCustomScrollbar())
        return false;

    std::unique_ptr<RenderStyle> scrollbarStyle = static_cast<RenderScrollbar*>(scrollbar)->getScrollbarPseudoStyle(ScrollbarBGPart, SCROLLBAR);
    return scrollbarStyle && scrollbarStyle->display() == NONE;
}

// FIXME: Can we make |layer| const RenderLayer&?
static void updateScrollingLayerWithClient(RenderLayer& layer, ChromeClient& client)
{
    auto* backing = layer.backing();
    ASSERT(backing);

    bool allowHorizontalScrollbar = !scrollbarHasDisplayNone(layer.horizontalScrollbar());
    bool allowVerticalScrollbar = !scrollbarHasDisplayNone(layer.verticalScrollbar());
    client.addOrUpdateScrollingLayer(layer.renderer().element(), backing->scrollingLayer()->platformLayer(), backing->scrollingContentsLayer()->platformLayer(),
        layer.scrollableContentsSize(), allowHorizontalScrollbar, allowVerticalScrollbar);
}

void RenderLayerCompositor::updateCustomLayersAfterFlush()
{
    registerAllViewportConstrainedLayers();

    if (!m_scrollingLayersNeedingUpdate.isEmpty()) {
        for (auto* layer : m_scrollingLayersNeedingUpdate)
            updateScrollingLayerWithClient(*layer, page().chrome().client());
        m_scrollingLayersNeedingUpdate.clear();
    }
    m_scrollingLayersNeedingUpdate.clear();
}
#endif

void RenderLayerCompositor::didFlushChangesForLayer(RenderLayer& layer, const GraphicsLayer* graphicsLayer)
{
    if (m_scrollCoordinatedLayers.contains(&layer))
        m_scrollCoordinatedLayersNeedingUpdate.add(&layer);

#if PLATFORM(IOS)
    if (m_scrollingLayers.contains(&layer))
        m_scrollingLayersNeedingUpdate.add(&layer);
#endif

    auto* backing = layer.backing();
    if (backing->backgroundLayerPaintsFixedRootBackground() && graphicsLayer == backing->backgroundLayer())
        fixedRootBackgroundLayerChanged();
}

void RenderLayerCompositor::didPaintBacking(RenderLayerBacking*)
{
    auto& frameView = m_renderView.frameView();
    frameView.setLastPaintTime(MonotonicTime::now());
    if (frameView.milestonesPendingPaint())
        frameView.firePaintRelatedMilestonesIfNeeded();
}

void RenderLayerCompositor::didChangeVisibleRect()
{
    auto* rootLayer = rootGraphicsLayer();
    if (!rootLayer)
        return;

    FloatRect visibleRect = visibleRectForLayerFlushing();
    bool requiresFlush = rootLayer->visibleRectChangeRequiresFlush(visibleRect);
    LOG_WITH_STREAM(Compositing, stream << "RenderLayerCompositor::didChangeVisibleRect " << visibleRect << " requiresFlush " << requiresFlush);
    if (requiresFlush)
        scheduleLayerFlushNow();
}

void RenderLayerCompositor::notifyFlushBeforeDisplayRefresh(const GraphicsLayer*)
{
    if (!m_layerUpdater) {
        PlatformDisplayID displayID = page().chrome().displayID();
        m_layerUpdater = std::make_unique<GraphicsLayerUpdater>(*this, displayID);
    }
    
    m_layerUpdater->scheduleUpdate();
}

void RenderLayerCompositor::flushLayersSoon(GraphicsLayerUpdater&)
{
    scheduleLayerFlush(true);
}

void RenderLayerCompositor::layerTiledBackingUsageChanged(const GraphicsLayer* graphicsLayer, bool usingTiledBacking)
{
    if (usingTiledBacking) {
        ++m_layersWithTiledBackingCount;
        graphicsLayer->tiledBacking()->setIsInWindow(page().isInWindow());
    } else {
        ASSERT(m_layersWithTiledBackingCount > 0);
        --m_layersWithTiledBackingCount;
    }
}

RenderLayerCompositor* RenderLayerCompositor::enclosingCompositorFlushingLayers() const
{
    for (auto* frame = &m_renderView.frameView().frame(); frame; frame = frame->tree().parent()) {
        auto* compositor = frame->contentRenderer() ? &frame->contentRenderer()->compositor() : nullptr;
        if (compositor->isFlushingLayers())
            return compositor;
    }
    
    return nullptr;
}

void RenderLayerCompositor::scheduleCompositingLayerUpdate()
{
    if (!m_updateCompositingLayersTimer.isActive())
        m_updateCompositingLayersTimer.startOneShot(0_s);
}

void RenderLayerCompositor::updateCompositingLayersTimerFired()
{
    updateCompositingLayers(CompositingUpdateType::AfterLayout);
}

bool RenderLayerCompositor::hasAnyAdditionalCompositedLayers(const RenderLayer& rootLayer) const
{
    int layerCount = m_compositedLayerCount + page().pageOverlayController().overlayCount();
    return layerCount > (rootLayer.isComposited() ? 1 : 0);
}

void RenderLayerCompositor::cancelCompositingLayerUpdate()
{
    m_updateCompositingLayersTimer.stop();
}

bool RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
{
    LOG_WITH_STREAM(Compositing, stream << "RenderLayerCompositor " << this << " updateCompositingLayers " << updateType << " root " << updateRoot);

    if (updateType == CompositingUpdateType::AfterStyleChange || updateType == CompositingUpdateType::AfterLayout)
        cacheAcceleratedCompositingFlagsAfterLayout(); // Some flags (e.g. forceCompositingMode) depend on layout.

    m_updateCompositingLayersTimer.stop();

    ASSERT(m_renderView.document().pageCacheState() == Document::NotInPageCache);
    
    // Compositing layers will be updated in Document::setVisualUpdatesAllowed(bool) if suppressed here.
    if (!m_renderView.document().visualUpdatesAllowed())
        return false;

    // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished.
    if (m_renderView.needsLayout())
        return false;

    if (!m_compositing && (m_forceCompositingMode || (isMainFrameCompositor() && page().pageOverlayController().overlayCount())))
        enableCompositingMode(true);

    if (!m_reevaluateCompositingAfterLayout && !m_compositing)
        return false;

    ++m_compositingUpdateCount;

    AnimationUpdateBlock animationUpdateBlock(&m_renderView.frameView().frame().animation());

    SetForScope<bool> postLayoutChange(m_inPostLayoutUpdate, true);
    
    bool checkForHierarchyUpdate = m_reevaluateCompositingAfterLayout;
    bool needGeometryUpdate = false;

    switch (updateType) {
    case CompositingUpdateType::AfterStyleChange:
    case CompositingUpdateType::AfterLayout:
    case CompositingUpdateType::OnHitTest:
        checkForHierarchyUpdate = true;
        break;
    case CompositingUpdateType::OnScroll:
    case CompositingUpdateType::OnCompositedScroll:
        checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
        needGeometryUpdate = true;
        break;
    }

    if (!checkForHierarchyUpdate && !needGeometryUpdate)
        return false;

    bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
    bool isFullUpdate = !updateRoot;

    // Only clear the flag if we're updating the entire hierarchy.
    m_compositingLayersNeedRebuild = false;
    updateRoot = &rootRenderLayer();

    if (isFullUpdate && updateType == CompositingUpdateType::AfterLayout)
        m_reevaluateCompositingAfterLayout = false;

    LOG(Compositing, " checkForHierarchyUpdate %d, needGeometryUpdate %d", checkForHierarchyUpdate, needHierarchyUpdate);

#if !LOG_DISABLED
    MonotonicTime startTime;
    if (compositingLogEnabled()) {
        ++m_rootLayerUpdateCount;
        startTime = MonotonicTime::now();
    }
#endif

    if (checkForHierarchyUpdate) {
        // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
        // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
        CompositingState compState(updateRoot);
        bool layersChanged = false;
        bool saw3DTransform = false;
        OverlapMap overlapTestRequestMap;
        computeCompositingRequirements(nullptr, *updateRoot, overlapTestRequestMap, compState, layersChanged, saw3DTransform);
        needHierarchyUpdate |= layersChanged;
    }

#if !LOG_DISABLED
    if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
        m_obligateCompositedLayerCount = 0;
        m_secondaryCompositedLayerCount = 0;
        m_obligatoryBackingStoreBytes = 0;
        m_secondaryBackingStoreBytes = 0;

        auto& frame = m_renderView.frameView().frame();
        bool isMainFrame = isMainFrameCompositor();
        LOG(Compositing, "\nUpdate %d of %s.\n", m_rootLayerUpdateCount, isMainFrame ? "main frame" : frame.tree().uniqueName().string().utf8().data());
    }
#endif

    if (needHierarchyUpdate) {
        // Update the hierarchy of the compositing layers.
        Vector<GraphicsLayer*> childList;
        rebuildCompositingLayerTree(*updateRoot, childList, 0);

        // Host the document layer in the RenderView's root layer.
        if (isFullUpdate) {
            appendDocumentOverlayLayers(childList);
            // Even when childList is empty, don't drop out of compositing mode if there are
            // composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
            if (childList.isEmpty() && !hasAnyAdditionalCompositedLayers(*updateRoot))
                destroyRootLayer();
            else if (m_rootContentLayer)
                m_rootContentLayer->setChildren(childList);
        }
        
        reattachSubframeScrollLayers();
    } else if (needGeometryUpdate) {
        // We just need to do a geometry update. This is only used for position:fixed scrolling;
        // most of the time, geometry is updated via RenderLayer::styleChanged().
        updateLayerTreeGeometry(*updateRoot, 0);
        ASSERT(!isFullUpdate || !m_subframeScrollLayersNeedReattach);
    }
    
#if !LOG_DISABLED
    if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
        MonotonicTime endTime = MonotonicTime::now();
        LOG(Compositing, "Total layers   primary   secondary   obligatory backing (KB)   secondary backing(KB)   total backing (KB)  update time (ms)\n");

        LOG(Compositing, "%8d %11d %9d %20.2f %22.2f %22.2f %18.2f\n",
            m_obligateCompositedLayerCount + m_secondaryCompositedLayerCount, m_obligateCompositedLayerCount,
            m_secondaryCompositedLayerCount, m_obligatoryBackingStoreBytes / 1024, m_secondaryBackingStoreBytes / 1024, (m_obligatoryBackingStoreBytes + m_secondaryBackingStoreBytes) / 1024, (endTime - startTime).milliseconds());
    }
#endif
    ASSERT(updateRoot || !m_compositingLayersNeedRebuild);

    if (!hasAcceleratedCompositing())
        enableCompositingMode(false);

    // Inform the inspector that the layer tree has changed.
    InspectorInstrumentation::layerTreeDidChange(&page());

    return true;
}

void RenderLayerCompositor::appendDocumentOverlayLayers(Vector<GraphicsLayer*>& childList)
{
    if (!isMainFrameCompositor() || !m_compositing)
        return;

    childList.append(&page().pageOverlayController().layerWithDocumentOverlays());
}

void RenderLayerCompositor::layerBecameNonComposited(const RenderLayer& layer)
{
    // Inform the inspector that the given RenderLayer was destroyed.
    InspectorInstrumentation::renderLayerDestroyed(&page(), layer);

    ASSERT(m_compositedLayerCount > 0);
    --m_compositedLayerCount;
}

#if !LOG_DISABLED
void RenderLayerCompositor::logLayerInfo(const RenderLayer& layer, int depth)
{
    if (!compositingLogEnabled())
        return;

    auto* backing = layer.backing();
    if (requiresCompositingLayer(layer) || layer.isRenderViewLayer()) {
        ++m_obligateCompositedLayerCount;
        m_obligatoryBackingStoreBytes += backing->backingStoreMemoryEstimate();
    } else {
        ++m_secondaryCompositedLayerCount;
        m_secondaryBackingStoreBytes += backing->backingStoreMemoryEstimate();
    }

    LayoutRect absoluteBounds = backing->compositedBounds();
    absoluteBounds.move(layer.offsetFromAncestor(m_renderView.layer()));
    
    StringBuilder logString;
    logString.append(String::format("%*p id %" PRIu64 " (%.3f,%.3f-%.3f,%.3f) %.2fKB", 12 + depth * 2, &layer, backing->graphicsLayer()->primaryLayerID(),
        absoluteBounds.x().toFloat(), absoluteBounds.y().toFloat(), absoluteBounds.maxX().toFloat(), absoluteBounds.maxY().toFloat(),
        backing->backingStoreMemoryEstimate() / 1024));
    
    if (!layer.renderer().style().hasAutoZIndex())
        logString.append(String::format(" z-index: %d", layer.renderer().style().zIndex())); 

    logString.appendLiteral(" (");
    logString.append(logReasonsForCompositing(layer));
    logString.appendLiteral(") ");

    if (backing->graphicsLayer()->contentsOpaque() || backing->paintsIntoCompositedAncestor() || backing->foregroundLayer() || backing->backgroundLayer()) {
        logString.append('[');
        bool prependSpace = false;
        if (backing->graphicsLayer()->contentsOpaque()) {
            logString.appendLiteral("opaque");
            prependSpace = true;
        }

        if (backing->paintsIntoCompositedAncestor()) {
            if (prependSpace)
                logString.appendLiteral(", ");
            logString.appendLiteral("paints into ancestor");
            prependSpace = true;
        }

        if (backing->foregroundLayer() || backing->backgroundLayer()) {
            if (prependSpace)
                logString.appendLiteral(", ");
            if (backing->foregroundLayer() && backing->backgroundLayer()) {
                logString.appendLiteral("+foreground+background");
                prependSpace = true;
            } else if (backing->foregroundLayer()) {
                logString.appendLiteral("+foreground");
                prependSpace = true;
            } else {
                logString.appendLiteral("+background");
                prependSpace = true;
            }
        }
        
        if (backing->paintsSubpixelAntialiasedText()) {
            if (prependSpace)
                logString.appendLiteral(", ");
            logString.appendLiteral("texty");
        }

        logString.appendLiteral("] ");
    }

    logString.append(layer.name());

    LOG(Compositing, "%s", logString.toString().utf8().data());
}
#endif

static bool checkIfDescendantClippingContextNeedsUpdate(const RenderLayer& layer, bool isClipping)
{
    for (auto* child = layer.firstChild(); child; child = child->nextSibling()) {
        auto* backing = child->backing();
        if (backing && (isClipping || backing->hasAncestorClippingLayer()))
            return true;

        if (checkIfDescendantClippingContextNeedsUpdate(*child, isClipping))
            return true;
    }
    return false;
}

#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
static bool isScrollableOverflow(EOverflow overflow)
{
    return overflow == OSCROLL || overflow == OAUTO || overflow == OOVERLAY;
}

static bool styleHasTouchScrolling(const RenderStyle& style)
{
    return style.useTouchOverflowScrolling() && (isScrollableOverflow(style.overflowX()) || isScrollableOverflow(style.overflowY()));
}
#endif

static bool styleChangeRequiresLayerRebuild(const RenderLayer& layer, const RenderStyle& oldStyle, const RenderStyle& newStyle)
{
    // Clip can affect ancestor compositing bounds, so we need recompute overlap when it changes on a non-composited layer.
    // FIXME: we should avoid doing this for all clip changes.
    if (oldStyle.clip() != newStyle.clip() || oldStyle.hasClip() != newStyle.hasClip())
        return true;

    // FIXME: need to check everything that we consult to avoid backing store here: webkit.org/b/138383
    if (!oldStyle.opacity() != !newStyle.opacity()) {
        auto* repaintContainer = layer.renderer().containerForRepaint();
        if (auto* ancestorBacking = repaintContainer ? repaintContainer->layer()->backing() : nullptr) {
            if (static_cast<bool>(newStyle.opacity()) != ancestorBacking->graphicsLayer()->drawsContent())
                return true;
        }
    }

    // When overflow changes, composited layers may need to update their ancestorClipping layers.
    if (!layer.isComposited() && (oldStyle.overflowX() != newStyle.overflowX() || oldStyle.overflowY() != newStyle.overflowY()) && layer.stackingContainer()->hasCompositingDescendant())
        return true;
    
#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
    if (styleHasTouchScrolling(oldStyle) != styleHasTouchScrolling(newStyle))
        return true;
#endif

    // Compositing layers keep track of whether they are clipped by any of the ancestors.
    // When the current layer's clipping behaviour changes, we need to propagate it to the descendants.
    bool wasClipping = oldStyle.hasClip() || oldStyle.overflowX() != OVISIBLE || oldStyle.overflowY() != OVISIBLE;
    bool isClipping = newStyle.hasClip() || newStyle.overflowX() != OVISIBLE || newStyle.overflowY() != OVISIBLE;
    if (isClipping != wasClipping) {
        if (checkIfDescendantClippingContextNeedsUpdate(layer, isClipping))
            return true;
    }

    return false;
}

void RenderLayerCompositor::layerStyleChanged(StyleDifference diff, RenderLayer& layer, const RenderStyle* oldStyle)
{
    if (diff == StyleDifferenceEqual)
        return;

    const RenderStyle& newStyle = layer.renderer().style();
    if (updateLayerCompositingState(layer) || (oldStyle && styleChangeRequiresLayerRebuild(layer, *oldStyle, newStyle))) {
        setCompositingLayersNeedRebuild();
        m_layerNeedsCompositingUpdate = true;
        return;
    }

    if (layer.isComposited()) {
        // FIXME: updating geometry here is potentially harmful, because layout is not up-to-date.
        layer.backing()->updateGeometry();
        layer.backing()->updateAfterDescendants();
        m_layerNeedsCompositingUpdate = true;
        return;
    }

    if (needsCompositingUpdateForStyleChangeOnNonCompositedLayer(layer, oldStyle))
        m_layerNeedsCompositingUpdate = true;
}

bool RenderLayerCompositor::needsCompositingUpdateForStyleChangeOnNonCompositedLayer(RenderLayer& layer, const RenderStyle* oldStyle) const
{
    // Needed for scroll bars.
    if (layer.isRenderViewLayer())
        return true;

    if (!oldStyle)
        return false;

    const RenderStyle& newStyle = layer.renderer().style();
    // Visibility change may affect geometry of the enclosing composited layer.
    if (oldStyle->visibility() != newStyle.visibility())
        return true;

    // We don't have any direct reasons for this style change to affect layer composition. Test if it might affect things indirectly.
    if (styleChangeMayAffectIndirectCompositingReasons(layer.renderer(), *oldStyle))
        return true;

    return false;
}

bool RenderLayerCompositor::canCompositeClipPath(const RenderLayer& layer)
{
    ASSERT(layer.isComposited());
    ASSERT(layer.renderer().style().clipPath());

    if (layer.renderer().hasMask())
        return false;

    auto& clipPath = *layer.renderer().style().clipPath();
    return (clipPath.type() != ClipPathOperation::Shape || clipPath.type() == ClipPathOperation::Shape) && GraphicsLayer::supportsLayerType(GraphicsLayer::Type::Shape);
}

static RenderLayerModelObject& rendererForCompositingTests(const RenderLayer& layer)
{
    auto* renderer = &layer.renderer();

    // The compositing state of a reflection should match that of its reflected layer.
    if (layer.isReflection())
        renderer = downcast<RenderLayerModelObject>(renderer->parent()); // The RenderReplica's parent is the object being reflected.

    return *renderer;
}

void RenderLayerCompositor::updateRootContentLayerClipping()
{
    m_rootContentLayer->setMasksToBounds(!m_renderView.settings().backgroundShouldExtendBeyondPage());
}

bool RenderLayerCompositor::updateBacking(RenderLayer& layer, CompositingChangeRepaint shouldRepaint, BackingRequired backingRequired)
{
    bool layerChanged = false;
    RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason;

    if (backingRequired == BackingRequired::Unknown)
        backingRequired = needsToBeComposited(layer, &viewportConstrainedNotCompositedReason) ? BackingRequired::Yes : BackingRequired::No;
    else {
        // Need to fetch viewportConstrainedNotCompositedReason, but without doing all the work that needsToBeComposited does.
        requiresCompositingForPosition(rendererForCompositingTests(layer), layer, &viewportConstrainedNotCompositedReason);
    }

    if (backingRequired == BackingRequired::Yes) {
        enableCompositingMode();
        
        if (!layer.backing()) {
            // If we need to repaint, do so before making backing
            if (shouldRepaint == CompositingChangeRepaintNow)
                repaintOnCompositingChange(layer);

            layer.ensureBacking();

            if (layer.isRenderViewLayer() && useCoordinatedScrollingForLayer(layer)) {
                updateScrollCoordinatedStatus(layer, { ScrollingNodeChangeFlags::Layer, ScrollingNodeChangeFlags::LayerGeometry });
                if (auto* scrollingCoordinator = this->scrollingCoordinator())
                    scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());
#if ENABLE(RUBBER_BANDING)
                updateLayerForHeader(page().headerHeight());
                updateLayerForFooter(page().footerHeight());
#endif
                updateRootContentLayerClipping();

                if (auto* tiledBacking = layer.backing()->tiledBacking())
                    tiledBacking->setTopContentInset(m_renderView.frameView().topContentInset());
            }

            // This layer and all of its descendants have cached repaints rects that are relative to
            // the repaint container, so change when compositing changes; we need to update them here.
            if (layer.parent())
                layer.computeRepaintRectsIncludingDescendants();

            layerChanged = true;
        }
    } else {
        if (layer.backing()) {
            // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to
            // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection 
            // are both either composited, or not composited.
            if (layer.isReflection()) {
                auto* sourceLayer = downcast<RenderLayerModelObject>(*layer.renderer().parent()).layer();
                if (auto* backing = sourceLayer->backing()) {
                    ASSERT(backing->graphicsLayer()->replicaLayer() == layer.backing()->graphicsLayer());
                    backing->graphicsLayer()->setReplicatedByLayer(nullptr);
                }
            }

            removeFromScrollCoordinatedLayers(layer);

            layer.clearBacking();
            layerChanged = true;

            // This layer and all of its descendants have cached repaints rects that are relative to
            // the repaint container, so change when compositing changes; we need to update them here.
            layer.computeRepaintRectsIncludingDescendants();

            // If we need to repaint, do so now that we've removed the backing
            if (shouldRepaint == CompositingChangeRepaintNow)
                repaintOnCompositingChange(layer);
        }
    }
    
#if ENABLE(VIDEO)
    if (layerChanged && is<RenderVideo>(layer.renderer())) {
        // If it's a video, give the media player a chance to hook up to the layer.
        downcast<RenderVideo>(layer.renderer()).acceleratedRenderingStateChanged();
    }
#endif

    if (layerChanged && is<RenderWidget>(layer.renderer())) {
        auto* innerCompositor = frameContentsCompositor(&downcast<RenderWidget>(layer.renderer()));
        if (innerCompositor && innerCompositor->inCompositingMode())
            innerCompositor->updateRootLayerAttachment();
    }
    
    if (layerChanged)
        layer.clearClipRectsIncludingDescendants(PaintingClipRects);

    // If a fixed position layer gained/lost a backing or the reason not compositing it changed,
    // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
    if (layer.renderer().isFixedPositioned()) {
        if (layer.viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) {
            layer.setViewportConstrainedNotCompositedReason(viewportConstrainedNotCompositedReason);
            layerChanged = true;
        }
        if (layerChanged) {
            if (auto* scrollingCoordinator = this->scrollingCoordinator())
                scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView.frameView());
        }
    } else
        layer.setViewportConstrainedNotCompositedReason(RenderLayer::NoNotCompositedReason);
    
    if (layer.backing())
        layer.backing()->updateDebugIndicators(m_showDebugBorders, m_showRepaintCounter);

    return layerChanged;
}

bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer& layer, CompositingChangeRepaint shouldRepaint)
{
    bool layerChanged = updateBacking(layer, shouldRepaint);

    // See if we need content or clipping layers. Methods called here should assume
    // that the compositing state of descendant layers has not been updated yet.
    if (layer.backing() && layer.backing()->updateConfiguration())
        layerChanged = true;

    return layerChanged;
}

void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer& layer)
{
    // If the renderer is not attached yet, no need to repaint.
    if (&layer.renderer() != &m_renderView && !layer.renderer().parent())
        return;

    auto* repaintContainer = layer.renderer().containerForRepaint();
    if (!repaintContainer)
        repaintContainer = &m_renderView;

    layer.repaintIncludingNonCompositingDescendants(repaintContainer);
    if (repaintContainer == &m_renderView) {
        // The contents of this layer may be moving between the window
        // and a GraphicsLayer, so we need to make sure the window system
        // synchronizes those changes on the screen.
        m_renderView.frameView().setNeedsOneShotDrawingSynchronization();
    }
}

// This method assumes that layout is up-to-date, unlike repaintOnCompositingChange().
void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer& layer, const LayoutRect& rect)
{
    auto* compositedAncestor = layer.enclosingCompositingLayerForRepaint(ExcludeSelf);
    if (!compositedAncestor)
        return;

    ASSERT(compositedAncestor->backing());
    LayoutRect repaintRect = rect;
    repaintRect.move(layer.offsetFromAncestor(compositedAncestor));
    compositedAncestor->setBackingNeedsRepaintInRect(repaintRect);

    // The contents of this layer may be moving from a GraphicsLayer to the window,
    // so we need to make sure the window system synchronizes those changes on the screen.
    if (compositedAncestor->isRenderViewLayer())
        m_renderView.frameView().setNeedsOneShotDrawingSynchronization();
}

void RenderLayerCompositor::layerWasAdded(RenderLayer&, RenderLayer&)
{
    setCompositingLayersNeedRebuild();
}

void RenderLayerCompositor::layerWillBeRemoved(RenderLayer& parent, RenderLayer& child)
{
    if (!child.isComposited() || parent.renderer().renderTreeBeingDestroyed())
        return;

    removeFromScrollCoordinatedLayers(child);
    repaintInCompositedAncestor(child, child.backing()->compositedBounds());

    setCompositingParent(child, nullptr);
    setCompositingLayersNeedRebuild();
}

RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer& layer) const
{
    for (auto* parent = layer.parent(); parent; parent = parent->parent()) {
        if (parent->isStackingContainer())
            return nullptr;
        if (parent->renderer().hasClipOrOverflowClip())
            return parent;
    }
    return nullptr;
}

void RenderLayerCompositor::computeExtent(const OverlapMap& overlapMap, const RenderLayer& layer, OverlapExtent& extent) const
{
    if (extent.extentComputed)
        return;

    LayoutRect layerBounds;
    if (extent.hasTransformAnimation)
        extent.animationCausesExtentUncertainty = !layer.getOverlapBoundsIncludingChildrenAccountingForTransformAnimations(layerBounds);
    else
        layerBounds = layer.overlapBounds();
    
    // In the animating transform case, we avoid double-accounting for the transform because
    // we told pushMappingsToAncestor() to ignore transforms earlier.
    extent.bounds = enclosingLayoutRect(overlapMap.geometryMap().absoluteRect(layerBounds));

    // Empty rects never intersect, but we need them to for the purposes of overlap testing.
    if (extent.bounds.isEmpty())
        extent.bounds.setSize(LayoutSize(1, 1));


    RenderLayerModelObject& renderer = layer.renderer();
    if (renderer.isFixedPositioned() && renderer.container() == &m_renderView) {
        // Because fixed elements get moved around without re-computing overlap, we have to compute an overlap
        // rect that covers all the locations that the fixed element could move to.
        // FIXME: need to handle sticky too.
        extent.bounds = m_renderView.frameView().fixedScrollableAreaBoundsInflatedForScrolling(extent.bounds);
    }

    extent.extentComputed = true;
}

void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, const RenderLayer& layer, OverlapExtent& extent)
{
    if (layer.isRenderViewLayer())
        return;

    computeExtent(overlapMap, layer, extent);

    LayoutRect clipRect = layer.backgroundClipRect(RenderLayer::ClipRectsContext(&rootRenderLayer(), AbsoluteClipRects)).rect(); // FIXME: Incorrect for CSS regions.

    // On iOS, pageScaleFactor() is not applied by RenderView, so we should not scale here.
    if (!m_renderView.settings().delegatesPageScaling())
        clipRect.scale(pageScaleFactor());
    clipRect.intersect(extent.bounds);
    overlapMap.add(clipRect);
}

void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, const RenderLayer& layer, const RenderLayer* ancestorLayer)
{
    if (!canBeComposited(layer))
        return;

    // A null ancestorLayer is an indication that 'layer' has already been pushed.
    if (ancestorLayer)
        overlapMap.geometryMap().pushMappingsToAncestor(&layer, ancestorLayer);
    
    OverlapExtent layerExtent;
    addToOverlapMap(overlapMap, layer, layerExtent);

#if !ASSERT_DISABLED
    LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(&layer));
#endif

    if (auto* negZOrderList = layer.negZOrderList()) {
        for (auto* renderLayer : *negZOrderList)
            addToOverlapMapRecursive(overlapMap, *renderLayer, &layer);
    }

    if (auto* normalFlowList = layer.normalFlowList()) {
        for (auto* renderLayer : *normalFlowList)
            addToOverlapMapRecursive(overlapMap, *renderLayer, &layer);
    }

    if (auto* posZOrderList = layer.posZOrderList()) {
        for (auto* renderLayer : *posZOrderList)
            addToOverlapMapRecursive(overlapMap, *renderLayer, &layer);
    }
    
    if (ancestorLayer)
        overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
}

//  Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
//  For the z-order children of a compositing layer:
//      If a child layers has a compositing layer, then all subsequent layers must
//      be compositing in order to render above that layer.
//
//      If a child in the negative z-order list is compositing, then the layer itself
//      must be compositing so that its contents render over that child.
//      This implies that its positive z-index children must also be compositing.
//
void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer& layer, OverlapMap& overlapMap, CompositingState& compositingState, bool& layersChanged, bool& descendantHas3DTransform)
{
    layer.updateDescendantDependentFlags();
    layer.updateLayerListsIfNeeded();

    // Clear the flag
    layer.setHasCompositingDescendant(false);
    layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::None);

    // Check if the layer needs to be composited for direct reasons (e.g. 3D transform).
    bool willBeComposited = needsToBeComposited(layer);

    OverlapExtent layerExtent;
    // Use the fact that we're composited as a hint to check for an animating transform.
    // FIXME: Maybe needsToBeComposited() should return a bitmask of reasons, to avoid the need to recompute things.
    if (willBeComposited && !layer.isRenderViewLayer())
        layerExtent.hasTransformAnimation = isRunningTransformAnimation(layer.renderer());

    bool respectTransforms = !layerExtent.hasTransformAnimation;
    overlapMap.geometryMap().pushMappingsToAncestor(&layer, ancestorLayer, respectTransforms);

    RenderLayer::IndirectCompositingReason compositingReason = compositingState.subtreeIsCompositing ? RenderLayer::IndirectCompositingReason::Stacking : RenderLayer::IndirectCompositingReason::None;

    // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map
    if (!willBeComposited && !overlapMap.isEmpty() && compositingState.testingOverlap) {
        computeExtent(overlapMap, layer, layerExtent);
        // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
        compositingReason = overlapMap.overlapsLayers(layerExtent.bounds) ? RenderLayer::IndirectCompositingReason::Overlap : RenderLayer::IndirectCompositingReason::None;
    }

#if ENABLE(VIDEO)
    // Video is special. It's the only RenderLayer type that can both have
    // RenderLayer children and whose children can't use its backing to render
    // into. These children (the controls) always need to be promoted into their
    // own layers to draw on top of the accelerated video.
    if (compositingState.compositingAncestor && compositingState.compositingAncestor->renderer().isVideo())
        compositingReason = RenderLayer::IndirectCompositingReason::Overlap;
#endif

    layer.setIndirectCompositingReason(compositingReason);

    // Check if the computed indirect reason will force the layer to become composited.
    if (!willBeComposited && layer.mustCompositeForIndirectReasons() && canBeComposited(layer))
        willBeComposited = true;
    ASSERT(willBeComposited == needsToBeComposited(layer));

    // The children of this layer don't need to composite, unless there is
    // a compositing layer among them, so start by inheriting the compositing
    // ancestor with subtreeIsCompositing set to false.
    CompositingState childState(compositingState);
    childState.subtreeIsCompositing = false;
#if ENABLE(CSS_COMPOSITING)
    childState.hasNotIsolatedCompositedBlendingDescendants = false;
#endif

    if (willBeComposited) {
        // Tell the parent it has compositing descendants.
        compositingState.subtreeIsCompositing = true;
        // This layer now acts as the ancestor for kids.
        childState.compositingAncestor = &layer;

        overlapMap.pushCompositingContainer();
        // This layer is going to be composited, so children can safely ignore the fact that there's an 
        // animation running behind this layer, meaning they can rely on the overlap map testing again.
        childState.testingOverlap = true;

        computeExtent(overlapMap, layer, layerExtent);
        childState.ancestorHasTransformAnimation |= layerExtent.hasTransformAnimation;
        // Too hard to compute animated bounds if both us and some ancestor is animating transform.
        layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation;
    }

#if !ASSERT_DISABLED
    LayerListMutationDetector mutationChecker(&layer);
#endif

    bool anyDescendantHas3DTransform = false;

    if (auto* negZOrderList = layer.negZOrderList()) {
        for (auto* renderLayer : *negZOrderList) {
            computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);

            // If we have to make a layer for this child, make one now so we can have a contents layer
            // (since we need to ensure that the -ve z-order child renders underneath our contents).
            if (!willBeComposited && childState.subtreeIsCompositing) {
                // make layer compositing
                layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::BackgroundLayer);
                childState.compositingAncestor = &layer;
                overlapMap.pushCompositingContainer();
                // This layer is going to be composited, so children can safely ignore the fact that there's an
                // animation running behind this layer, meaning they can rely on the overlap map testing again
                childState.testingOverlap = true;
                willBeComposited = true;
            }
        }
    }
    
    if (auto* normalFlowList = layer.normalFlowList()) {
        for (auto* renderLayer : *normalFlowList)
            computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
    }

    if (auto* posZOrderList = layer.posZOrderList()) {
        ASSERT(layer.isStackingContainer());
        for (auto* renderLayer : *posZOrderList)
            computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
    }

    // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
    if (layer.isRenderViewLayer()) {
        if (inCompositingMode() && m_hasAcceleratedCompositing)
            willBeComposited = true;
    }
    
    ASSERT(willBeComposited == needsToBeComposited(layer));

    // All layers (even ones that aren't being composited) need to get added to
    // the overlap map. Layers that do not composite will draw into their
    // compositing ancestor's backing, and so are still considered for overlap.
    // FIXME: When layerExtent has taken animation bounds into account, we also know that the bounds
    // include descendants, so we don't need to add them all to the overlap map.
    if (childState.compositingAncestor && !childState.compositingAncestor->isRenderViewLayer())
        addToOverlapMap(overlapMap, layer, layerExtent);

#if ENABLE(CSS_COMPOSITING)
    layer.setHasNotIsolatedCompositedBlendingDescendants(childState.hasNotIsolatedCompositedBlendingDescendants);
    ASSERT(!layer.hasNotIsolatedCompositedBlendingDescendants() || layer.hasNotIsolatedBlendingDescendants());
#endif
    // Now check for reasons to become composited that depend on the state of descendant layers.
    RenderLayer::IndirectCompositingReason indirectCompositingReason;
    if (!willBeComposited && canBeComposited(layer)
        && requiresCompositingForIndirectReason(layer.renderer(), childState.subtreeIsCompositing, anyDescendantHas3DTransform, indirectCompositingReason)) {
        layer.setIndirectCompositingReason(indirectCompositingReason);
        childState.compositingAncestor = &layer;
        overlapMap.pushCompositingContainer();
        addToOverlapMapRecursive(overlapMap, layer);
        willBeComposited = true;
    }
    
    ASSERT(willBeComposited == needsToBeComposited(layer));
    if (layer.reflectionLayer()) {
        // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
        layer.reflectionLayer()->setIndirectCompositingReason(willBeComposited ? RenderLayer::IndirectCompositingReason::Stacking : RenderLayer::IndirectCompositingReason::None);
    }

    // Subsequent layers in the parent stacking context also need to composite.
    if (childState.subtreeIsCompositing)
        compositingState.subtreeIsCompositing = true;

    // Set the flag to say that this layer has compositing children.
    layer.setHasCompositingDescendant(childState.subtreeIsCompositing);

    // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping, so test that again.
    bool isCompositedClippingLayer = canBeComposited(layer) && clipsCompositingDescendants(layer);

    // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.
    // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because
    // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.
    if ((!childState.testingOverlap && !isCompositedClippingLayer) || layerExtent.knownToBeHaveExtentUncertainty())
        compositingState.testingOverlap = false;
    
    if (isCompositedClippingLayer) {
        if (!willBeComposited) {
            childState.compositingAncestor = &layer;
            overlapMap.pushCompositingContainer();
            addToOverlapMapRecursive(overlapMap, layer);
            willBeComposited = true;
         }
    }

#if ENABLE(CSS_COMPOSITING)
    if ((willBeComposited && layer.hasBlendMode())
        || (layer.hasNotIsolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending()))
        compositingState.hasNotIsolatedCompositedBlendingDescendants = true;
#endif

    if (childState.compositingAncestor == &layer && !layer.isRenderViewLayer())
        overlapMap.popCompositingContainer();

    // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
    // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode
    // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
    if (layer.isRenderViewLayer() && !childState.subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode && !hasAnyAdditionalCompositedLayers(layer)) {
        // Don't drop out of compositing on iOS, because we may flash. See <rdar://problem/8348337>.
#if !PLATFORM(IOS)
        enableCompositingMode(false);
        willBeComposited = false;
#endif
    }
    
    ASSERT(willBeComposited == needsToBeComposited(layer));

    // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
    if (updateBacking(layer, CompositingChangeRepaintNow, willBeComposited ? BackingRequired::Yes : BackingRequired::No))
        layersChanged = true;

    if (layer.reflectionLayer() && updateLayerCompositingState(*layer.reflectionLayer(), CompositingChangeRepaintNow))
        layersChanged = true;

    descendantHas3DTransform |= anyDescendantHas3DTransform || layer.has3DTransform();

    overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
}

void RenderLayerCompositor::setCompositingParent(RenderLayer& childLayer, RenderLayer* parentLayer)
{
    ASSERT(!parentLayer || childLayer.ancestorCompositingLayer() == parentLayer);
    ASSERT(childLayer.isComposited());

    // It's possible to be called with a parent that isn't yet composited when we're doing
    // partial updates as required by painting or hit testing. Just bail in that case;
    // we'll do a full layer update soon.
    if (!parentLayer || !parentLayer->isComposited())
        return;

    if (parentLayer) {
        auto* hostingLayer = parentLayer->backing()->parentForSublayers();
        auto* hostedLayer = childLayer.backing()->childForSuperlayers();
        
        hostingLayer->addChild(hostedLayer);
    } else
        childLayer.backing()->childForSuperlayers()->removeFromParent();
}

void RenderLayerCompositor::removeCompositedChildren(RenderLayer& layer)
{
    ASSERT(layer.isComposited());

    layer.backing()->parentForSublayers()->removeAllChildren();
}

#if ENABLE(VIDEO)
bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo& video) const
{
    if (!m_hasAcceleratedCompositing)
        return false;

    return video.supportsAcceleratedRendering();
}
#endif

void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer& layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth)
{
    // Make the layer compositing if necessary, and set up clipping and content layers.
    // Note that we can only do work here that is independent of whether the descendant layers
    // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.

    auto* layerBacking = layer.backing();
    if (layerBacking) {
        // The compositing state of all our children has been updated already, so now
        // we can compute and cache the composited bounds for this layer.
        layerBacking->updateCompositedBounds();

        if (auto* reflection = layer.reflectionLayer()) {
            if (reflection->backing())
                reflection->backing()->updateCompositedBounds();
        }

        if (layerBacking->updateConfiguration())
            layerBacking->updateDebugIndicators(m_showDebugBorders, m_showRepaintCounter);
        
        layerBacking->updateGeometry();

        if (!layer.parent())
            updateRootLayerPosition();

#if !LOG_DISABLED
        logLayerInfo(layer, depth);
#else
        UNUSED_PARAM(depth);
#endif
        if (layerBacking->hasUnpositionedOverflowControlsLayers())
            layer.positionNewlyCreatedOverflowControls();
    }

    // If this layer has backing, then we are collecting its children, otherwise appending
    // to the compositing child list of an enclosing layer.
    Vector<GraphicsLayer*> layerChildren;
    Vector<GraphicsLayer*>& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;

#if !ASSERT_DISABLED
    LayerListMutationDetector mutationChecker(&layer);
#endif

    if (auto* negZOrderList = layer.negZOrderList()) {
        for (auto* renderLayer : *negZOrderList)
            rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);

        // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
        if (layerBacking && layerBacking->foregroundLayer())
            childList.append(layerBacking->foregroundLayer());
    }

    if (auto* normalFlowList = layer.normalFlowList()) {
        for (auto* renderLayer : *normalFlowList)
            rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);
    }
    
    if (auto* posZOrderList = layer.posZOrderList()) {
        for (auto* renderLayer : *posZOrderList)
            rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);
    }

    if (layerBacking) {
        bool parented = false;
        if (is<RenderWidget>(layer.renderer()))
            parented = parentFrameContentLayers(&downcast<RenderWidget>(layer.renderer()));

        if (!parented)
            layerBacking->parentForSublayers()->setChildren(layerChildren);

        // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
        // Otherwise, the overflow control layers are normal children.
        if (!layerBacking->hasClippingLayer() && !layerBacking->hasScrollingLayer()) {
            if (auto* overflowControlLayer = layerBacking->layerForHorizontalScrollbar()) {
                overflowControlLayer->removeFromParent();
                layerBacking->parentForSublayers()->addChild(overflowControlLayer);
            }

            if (auto* overflowControlLayer = layerBacking->layerForVerticalScrollbar()) {
                overflowControlLayer->removeFromParent();
                layerBacking->parentForSublayers()->addChild(overflowControlLayer);
            }

            if (auto* overflowControlLayer = layerBacking->layerForScrollCorner()) {
                overflowControlLayer->removeFromParent();
                layerBacking->parentForSublayers()->addChild(overflowControlLayer);
            }
        }

        childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
    }
    
    if (auto* layerBacking = layer.backing())
        layerBacking->updateAfterDescendants();
}

void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
{
    if (m_overflowControlsHostLayer)
        m_overflowControlsHostLayer->setPosition(contentsOffset);
}

void RenderLayerCompositor::frameViewDidChangeSize()
{
    if (m_clipLayer) {
        const FrameView& frameView = m_renderView.frameView();
        m_clipLayer->setSize(frameView.sizeForVisibleContent());
        m_clipLayer->setPosition(positionForClipLayer());

        frameViewDidScroll();
        updateOverflowControlsLayers();

#if ENABLE(RUBBER_BANDING)
        if (m_layerForOverhangAreas) {
            m_layerForOverhangAreas->setSize(frameView.frameRect().size());
            m_layerForOverhangAreas->setPosition(FloatPoint(0, m_renderView.frameView().topContentInset()));
        }
#endif
    }
}

bool RenderLayerCompositor::hasCoordinatedScrolling() const
{
    auto* scrollingCoordinator = this->scrollingCoordinator();
    return scrollingCoordinator && scrollingCoordinator->coordinatesScrollingForFrameView(m_renderView.frameView());
}

void RenderLayerCompositor::updateScrollLayerPosition()
{
    ASSERT(m_scrollLayer);

    auto& frameView = m_renderView.frameView();
    IntPoint scrollPosition = frameView.scrollPosition();

    m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));

    if (auto* fixedBackgroundLayer = fixedRootBackgroundLayer())
        fixedBackgroundLayer->setPosition(frameView.scrollPositionForFixedPosition());
}

FloatPoint RenderLayerCompositor::positionForClipLayer() const
{
    auto& frameView = m_renderView.frameView();

    return FloatPoint(
        frameView.shouldPlaceBlockDirectionScrollbarOnLeft() ? frameView.horizontalScrollbarIntrusion() : 0,
        FrameView::yPositionForInsetClipLayer(frameView.scrollPosition(), frameView.topContentInset()));
}

void RenderLayerCompositor::frameViewDidScroll()
{
    if (!m_scrollLayer)
        return;

    // If there's a scrolling coordinator that manages scrolling for this frame view,
    // it will also manage updating the scroll layer position.
    if (hasCoordinatedScrolling()) {
        // We have to schedule a flush in order for the main TiledBacking to update its tile coverage.
        scheduleLayerFlushNow();
        return;
    }

    updateScrollLayerPosition();
}

void RenderLayerCompositor::frameViewDidAddOrRemoveScrollbars()
{
    updateOverflowControlsLayers();
}

void RenderLayerCompositor::frameViewDidLayout()
{
    if (auto* renderViewBacking = m_renderView.layer()->backing())
        renderViewBacking->adjustTiledBackingCoverage();
}

void RenderLayerCompositor::rootFixedBackgroundsChanged()
{
    auto* renderViewBacking = m_renderView.layer()->backing();
    if (renderViewBacking && renderViewBacking->isFrameLayerWithTiledBacking())
        setCompositingLayersNeedRebuild();
}

void RenderLayerCompositor::scrollingLayerDidChange(RenderLayer& layer)
{
    if (auto* scrollingCoordinator = this->scrollingCoordinator())
        scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer);
}

void RenderLayerCompositor::fixedRootBackgroundLayerChanged()
{
    if (m_renderView.renderTreeBeingDestroyed())
        return;

    if (m_renderView.layer()->isComposited())
        updateScrollCoordinatedStatus(*m_renderView.layer(), ScrollingNodeChangeFlags::Layer);
}

String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
{
    updateCompositingLayers(CompositingUpdateType::AfterLayout);

    if (!m_rootContentLayer)
        return String();

    flushPendingLayerChanges(true);

    LayerTreeAsTextBehavior layerTreeBehavior = LayerTreeAsTextBehaviorNormal;
    if (flags & LayerTreeFlagsIncludeDebugInfo)
        layerTreeBehavior |= LayerTreeAsTextDebug;
    if (flags & LayerTreeFlagsIncludeVisibleRects)
        layerTreeBehavior |= LayerTreeAsTextIncludeVisibleRects;
    if (flags & LayerTreeFlagsIncludeTileCaches)
        layerTreeBehavior |= LayerTreeAsTextIncludeTileCaches;
    if (flags & LayerTreeFlagsIncludeRepaintRects)
        layerTreeBehavior |= LayerTreeAsTextIncludeRepaintRects;
    if (flags & LayerTreeFlagsIncludePaintingPhases)
        layerTreeBehavior |= LayerTreeAsTextIncludePaintingPhases;
    if (flags & LayerTreeFlagsIncludeContentLayers)
        layerTreeBehavior |= LayerTreeAsTextIncludeContentLayers;
    if (flags & LayerTreeFlagsIncludeAcceleratesDrawing)
        layerTreeBehavior |= LayerTreeAsTextIncludeAcceleratesDrawing;
    if (flags & LayerTreeFlagsIncludeBackingStoreAttached)
        layerTreeBehavior |= LayerTreeAsTextIncludeBackingStoreAttached;

    // We skip dumping the scroll and clip layers to keep layerTreeAsText output
    // similar between platforms.
    String layerTreeText = m_rootContentLayer->layerTreeAsText(layerTreeBehavior);

    // Dump an empty layer tree only if the only composited layer is the main frame's tiled backing,
    // so that tests expecting us to drop out of accelerated compositing when there are no layers succeed.
    if (!hasAnyAdditionalCompositedLayers(rootRenderLayer()) && documentUsesTiledBacking() && !(layerTreeBehavior & LayerTreeAsTextIncludeTileCaches))
        layerTreeText = emptyString();

    // The true root layer is not included in the dump, so if we want to report
    // its repaint rects, they must be included here.
    if (flags & LayerTreeFlagsIncludeRepaintRects)
        return m_renderView.frameView().trackedRepaintRectsAsText() + layerTreeText;

    return layerTreeText;
}

RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderWidget* renderer)
{
    if (auto* contentDocument = renderer->frameOwnerElement().contentDocument()) {
        if (auto* view = contentDocument->renderView())
            return &view->compositor();
    }
    return nullptr;
}

bool RenderLayerCompositor::parentFrameContentLayers(RenderWidget* renderer)
{
    auto* innerCompositor = frameContentsCompositor(renderer);
    if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
        return false;
    
    auto* layer = renderer->layer();
    if (!layer->isComposited())
        return false;

    auto* backing = layer->backing();
    auto* hostingLayer = backing->parentForSublayers();
    auto* rootLayer = innerCompositor->rootGraphicsLayer();
    if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
        hostingLayer->removeAllChildren();
        hostingLayer->addChild(rootLayer);
    }
    return true;
}

// This just updates layer geometry without changing the hierarchy.
void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer& layer, int depth)
{
    if (auto* layerBacking = layer.backing()) {
        // The compositing state of all our children has been updated already, so now
        // we can compute and cache the composited bounds for this layer.
        layerBacking->updateCompositedBounds();

        if (auto* reflection = layer.reflectionLayer()) {
            if (reflection->backing())
                reflection->backing()->updateCompositedBounds();
        }

        layerBacking->updateConfiguration();
        layerBacking->updateGeometry();

        if (!layer.parent())
            updateRootLayerPosition();

#if !LOG_DISABLED
        logLayerInfo(layer, depth);
#else
        UNUSED_PARAM(depth);
#endif
    }

#if !ASSERT_DISABLED
    LayerListMutationDetector mutationChecker(&layer);
#endif

    if (auto* negZOrderList = layer.negZOrderList()) {
        for (auto* renderLayer : *negZOrderList)
            updateLayerTreeGeometry(*renderLayer, depth + 1);
    }

    if (auto* normalFlowList = layer.normalFlowList()) {
        for (auto* renderLayer : *normalFlowList)
            updateLayerTreeGeometry(*renderLayer, depth + 1);
    }
    
    if (auto* posZOrderList = layer.posZOrderList()) {
        for (auto* renderLayer : *posZOrderList)
            updateLayerTreeGeometry(*renderLayer, depth + 1);
    }

    if (auto* layerBacking = layer.backing())
        layerBacking->updateAfterDescendants();
}

// Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer& compositingAncestor, RenderLayer& layer)
{
    if (&layer != &compositingAncestor) {
        if (auto* layerBacking = layer.backing()) {
            layerBacking->updateCompositedBounds();

            if (auto* reflection = layer.reflectionLayer()) {
                if (reflection->backing())
                    reflection->backing()->updateCompositedBounds();
            }

            layerBacking->updateGeometry();
            layerBacking->updateAfterDescendants();
            return;
        }
    }

    if (layer.reflectionLayer())
        updateCompositingDescendantGeometry(compositingAncestor, *layer.reflectionLayer());

    if (!layer.hasCompositingDescendant())
        return;

#if !ASSERT_DISABLED
    LayerListMutationDetector mutationChecker(&layer);
#endif
    
    if (auto* negZOrderList = layer.negZOrderList()) {
        for (auto* renderLayer : *negZOrderList)
            updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
    }

    if (auto* normalFlowList = layer.normalFlowList()) {
        for (auto* renderLayer : *normalFlowList)
            updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
    }
    
    if (auto* posZOrderList = layer.posZOrderList()) {
        for (auto* renderLayer : *posZOrderList)
            updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
    }
    
    if (&layer != &compositingAncestor) {
        if (auto* layerBacking = layer.backing())
            layerBacking->updateAfterDescendants();
    }
}

void RenderLayerCompositor::repaintCompositedLayers()
{
    recursiveRepaintLayer(rootRenderLayer());
}

void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer& layer)
{
    // FIXME: This method does not work correctly with transforms.
    if (layer.isComposited() && !layer.backing()->paintsIntoCompositedAncestor())
        layer.setBackingNeedsRepaint();

#if !ASSERT_DISABLED
    LayerListMutationDetector mutationChecker(&layer);
#endif

    if (layer.hasCompositingDescendant()) {
        if (auto* negZOrderList = layer.negZOrderList()) {
            for (auto* renderLayer : *negZOrderList)
                recursiveRepaintLayer(*renderLayer);
        }

        if (auto* posZOrderList = layer.posZOrderList()) {
            for (auto* renderLayer : *posZOrderList)
                recursiveRepaintLayer(*renderLayer);
        }
    }
    if (auto* normalFlowList = layer.normalFlowList()) {
        for (auto* renderLayer : *normalFlowList)
            recursiveRepaintLayer(*renderLayer);
    }
}

RenderLayer& RenderLayerCompositor::rootRenderLayer() const
{
    return *m_renderView.layer();
}

GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
{
    if (m_overflowControlsHostLayer)
        return m_overflowControlsHostLayer.get();
    return m_rootContentLayer.get();
}

void RenderLayerCompositor::setIsInWindow(bool isInWindow)
{
    LOG(Compositing, "RenderLayerCompositor %p setIsInWindow %d", this, isInWindow);

    if (!inCompositingMode())
        return;

    if (auto* rootLayer = rootGraphicsLayer()) {
        GraphicsLayer::traverse(*rootLayer, [isInWindow](GraphicsLayer& layer) {
            layer.setIsInWindow(isInWindow);
        });
    }

    if (isInWindow) {
        if (m_rootLayerAttachment != RootLayerUnattached)
            return;

        RootLayerAttachment attachment = isMainFrameCompositor() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
        attachRootLayer(attachment);
#if PLATFORM(IOS)
        registerAllViewportConstrainedLayers();
        registerAllScrollingLayers();
#endif
    } else {
        if (m_rootLayerAttachment == RootLayerUnattached)
            return;

        detachRootLayer();
#if PLATFORM(IOS)
        unregisterAllViewportConstrainedLayers();
        unregisterAllScrollingLayers();
#endif
    }
}

void RenderLayerCompositor::clearBackingForLayerIncludingDescendants(RenderLayer& layer)
{
    if (layer.isComposited()) {
        removeFromScrollCoordinatedLayers(layer);
        layer.clearBacking();
    }

    for (auto* childLayer = layer.firstChild(); childLayer; childLayer = childLayer->nextSibling())
        clearBackingForLayerIncludingDescendants(*childLayer);
}

void RenderLayerCompositor::clearBackingForAllLayers()
{
    clearBackingForLayerIncludingDescendants(*m_renderView.layer());
}

void RenderLayerCompositor::updateRootLayerPosition()
{
    if (m_rootContentLayer) {
        m_rootContentLayer->setSize(m_renderView.frameView().contentsSize());
        m_rootContentLayer->setPosition(m_renderView.frameView().positionForRootContentLayer());
        m_rootContentLayer->setAnchorPoint(FloatPoint3D());
    }
    if (m_clipLayer) {
        m_clipLayer->setSize(m_renderView.frameView().sizeForVisibleContent());
        m_clipLayer->setPosition(positionForClipLayer());
    }

#if ENABLE(RUBBER_BANDING)
    if (m_contentShadowLayer) {
        m_contentShadowLayer->setPosition(m_rootContentLayer->position());
        m_contentShadowLayer->setSize(m_rootContentLayer->size());
    }

    updateLayerForTopOverhangArea(m_layerForTopOverhangArea != nullptr);
    updateLayerForBottomOverhangArea(m_layerForBottomOverhangArea != nullptr);
    updateLayerForHeader(m_layerForHeader != nullptr);
    updateLayerForFooter(m_layerForFooter != nullptr);
#endif
}

bool RenderLayerCompositor::has3DContent() const
{
    return layerHas3DContent(rootRenderLayer());
}

bool RenderLayerCompositor::needsToBeComposited(const RenderLayer& layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
{
    if (!canBeComposited(layer))
        return false;

    return requiresCompositingLayer(layer, viewportConstrainedNotCompositedReason) || layer.mustCompositeForIndirectReasons() || (inCompositingMode() && layer.isRenderViewLayer());
}

// Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
// Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
// static
bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer& layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
{
    auto& renderer = rendererForCompositingTests(layer);

    // The root layer always has a compositing layer, but it may not have backing.
    return requiresCompositingForTransform(renderer)
        || requiresCompositingForAnimation(renderer)
        || clipsCompositingDescendants(*renderer.layer())
        || requiresCompositingForPosition(renderer, *renderer.layer(), viewportConstrainedNotCompositedReason)
        || requiresCompositingForCanvas(renderer)
        || requiresCompositingForFilters(renderer)
        || requiresCompositingForWillChange(renderer)
        || requiresCompositingForBackfaceVisibility(renderer)
        || requiresCompositingForVideo(renderer)
        || requiresCompositingForFrame(renderer)
        || requiresCompositingForPlugin(renderer)
#if PLATFORM(IOS)
        || requiresCompositingForScrolling(*renderer.layer())
#endif
        || requiresCompositingForOverflowScrolling(*renderer.layer());
}

bool RenderLayerCompositor::canBeComposited(const RenderLayer& layer) const
{
    if (m_hasAcceleratedCompositing && layer.isSelfPaintingLayer()) {
        if (!layer.isInsideFragmentedFlow())
            return true;

        // CSS Regions flow threads do not need to be composited as we use composited RenderFragmentContainers
        // to render the background of the RenderFragmentedFlow.
        if (layer.isRenderFragmentedFlow())
            return false;

        return true;
    }
    return false;
}

bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer& layer, const RenderLayer* compositingAncestorLayer, const LayoutRect& layerCompositedBoundsInAncestor, const LayoutRect& ancestorCompositedBounds) const
{
    auto& renderer = layer.renderer();

    if (compositingAncestorLayer
        && !(compositingAncestorLayer->backing()->graphicsLayer()->drawsContent()
            || compositingAncestorLayer->backing()->paintsIntoWindow()
            || compositingAncestorLayer->backing()->paintsIntoCompositedAncestor()))
        return true;

    if (layer.isRenderViewLayer()
        || layer.transform() // note: excludes perspective and transformStyle3D.
        || requiresCompositingForAnimation(renderer)
        || requiresCompositingForPosition(renderer, layer)
        || requiresCompositingForCanvas(renderer)
        || requiresCompositingForFilters(renderer)
        || requiresCompositingForWillChange(renderer)
        || requiresCompositingForBackfaceVisibility(renderer)
        || requiresCompositingForVideo(renderer)
        || requiresCompositingForFrame(renderer)
        || requiresCompositingForPlugin(renderer)
        || requiresCompositingForOverflowScrolling(layer)
#if PLATFORM(IOS)
        || requiresCompositingForScrolling(layer)
#endif
        || renderer.isTransparent()
        || renderer.hasMask()
        || renderer.hasReflection()
        || renderer.hasFilter()
        || renderer.hasBackdropFilter())
        return true;

    if (layer.mustCompositeForIndirectReasons()) {
        RenderLayer::IndirectCompositingReason reason = layer.indirectCompositingReason();
        return reason == RenderLayer::IndirectCompositingReason::Overlap
            || reason == RenderLayer::IndirectCompositingReason::Stacking
            || reason == RenderLayer::IndirectCompositingReason::BackgroundLayer
            || reason == RenderLayer::IndirectCompositingReason::GraphicalEffect
            || reason == RenderLayer::IndirectCompositingReason::Preserve3D; // preserve-3d has to create backing store to ensure that 3d-transformed elements intersect.
    }

    if (!ancestorCompositedBounds.contains(layerCompositedBoundsInAncestor))
        return true;

    return false;
}

OptionSet<CompositingReason> RenderLayerCompositor::reasonsForCompositing(const RenderLayer& layer) const
{
    OptionSet<CompositingReason> reasons;

    if (!layer.isComposited())
        return reasons;

    auto& renderer = rendererForCompositingTests(layer);

    if (requiresCompositingForTransform(renderer))
        reasons |= CompositingReason::Transform3D;

    if (requiresCompositingForVideo(renderer))
        reasons |= CompositingReason::Video;
    else if (requiresCompositingForCanvas(renderer))
        reasons |= CompositingReason::Canvas;
    else if (requiresCompositingForPlugin(renderer))
        reasons |= CompositingReason::Plugin;
    else if (requiresCompositingForFrame(renderer))
        reasons |= CompositingReason::IFrame;

    if ((canRender3DTransforms() && renderer.style().backfaceVisibility() == BackfaceVisibilityHidden))
        reasons |= CompositingReason::BackfaceVisibilityHidden;

    if (clipsCompositingDescendants(*renderer.layer()))
        reasons |= CompositingReason::ClipsCompositingDescendants;

    if (requiresCompositingForAnimation(renderer))
        reasons |= CompositingReason::Animation;

    if (requiresCompositingForFilters(renderer))
        reasons |= CompositingReason::Filters;

    if (requiresCompositingForWillChange(renderer))
        reasons |= CompositingReason::WillChange;

    if (requiresCompositingForPosition(renderer, *renderer.layer()))
        reasons |= renderer.isFixedPositioned() ? CompositingReason::PositionFixed : CompositingReason::PositionSticky;

#if PLATFORM(IOS)
    if (requiresCompositingForScrolling(*renderer.layer()))
        reasons |= CompositingReason::OverflowScrollingTouch;
#endif

    if (requiresCompositingForOverflowScrolling(*renderer.layer()))
        reasons |= CompositingReason::OverflowScrollingTouch;

    switch (renderer.layer()->indirectCompositingReason()) {
    case RenderLayer::IndirectCompositingReason::None:
        break;
    case RenderLayer::IndirectCompositingReason::Stacking:
        reasons |= CompositingReason::Stacking;
        break;
    case RenderLayer::IndirectCompositingReason::Overlap:
        reasons |= CompositingReason::Overlap;
        break;
    case RenderLayer::IndirectCompositingReason::BackgroundLayer:
        reasons |= CompositingReason::NegativeZIndexChildren;
        break;
    case RenderLayer::IndirectCompositingReason::GraphicalEffect:
        if (renderer.hasTransform())
            reasons |= CompositingReason::TransformWithCompositedDescendants;

        if (renderer.isTransparent())
            reasons |= CompositingReason::OpacityWithCompositedDescendants;

        if (renderer.hasMask())
            reasons |= CompositingReason::MaskWithCompositedDescendants;

        if (renderer.hasReflection())
            reasons |= CompositingReason::ReflectionWithCompositedDescendants;

        if (renderer.hasFilter() || renderer.hasBackdropFilter())
            reasons |= CompositingReason::FilterWithCompositedDescendants;

#if ENABLE(CSS_COMPOSITING)
        if (layer.isolatesCompositedBlending())
            reasons |= CompositingReason::IsolatesCompositedBlendingDescendants;

        if (layer.hasBlendMode())
            reasons |= CompositingReason::BlendingWithCompositedDescendants;
#endif
        break;
    case RenderLayer::IndirectCompositingReason::Perspective:
        reasons |= CompositingReason::Perspective;
        break;
    case RenderLayer::IndirectCompositingReason::Preserve3D:
        reasons |= CompositingReason::Preserve3D;
        break;
    }

    if (inCompositingMode() && renderer.layer()->isRenderViewLayer())
        reasons |= CompositingReason::Root;

    return reasons;
}

#if !LOG_DISABLED
const char* RenderLayerCompositor::logReasonsForCompositing(const RenderLayer& layer)
{
    OptionSet<CompositingReason> reasons = reasonsForCompositing(layer);

    if (reasons.contains(CompositingReason::Transform3D))
        return "3D transform";

    if (reasons.contains(CompositingReason::Video))
        return "video";

    if (reasons.contains(CompositingReason::Canvas))
        return "canvas";

    if (reasons.contains(CompositingReason::Plugin))
        return "plugin";

    if (reasons.contains(CompositingReason::IFrame))
        return "iframe";

    if (reasons.contains(CompositingReason::BackfaceVisibilityHidden))
        return "backface-visibility: hidden";

    if (reasons.contains(CompositingReason::ClipsCompositingDescendants))
        return "clips compositing descendants";

    if (reasons.contains(CompositingReason::Animation))
        return "animation";

    if (reasons.contains(CompositingReason::Filters))
        return "filters";

    if (reasons.contains(CompositingReason::PositionFixed))
        return "position: fixed";

    if (reasons.contains(CompositingReason::PositionSticky))
        return "position: sticky";

    if (reasons.contains(CompositingReason::OverflowScrollingTouch))
        return "-webkit-overflow-scrolling: touch";

    if (reasons.contains(CompositingReason::Stacking))
        return "stacking";

    if (reasons.contains(CompositingReason::Overlap))
        return "overlap";

    if (reasons.contains(CompositingReason::NegativeZIndexChildren))
        return "negative z-index children";

    if (reasons.contains(CompositingReason::TransformWithCompositedDescendants))
        return "transform with composited descendants";

    if (reasons.contains(CompositingReason::OpacityWithCompositedDescendants))
        return "opacity with composited descendants";

    if (reasons.contains(CompositingReason::MaskWithCompositedDescendants))
        return "mask with composited descendants";

    if (reasons.contains(CompositingReason::ReflectionWithCompositedDescendants))
        return "reflection with composited descendants";

    if (reasons.contains(CompositingReason::FilterWithCompositedDescendants))
        return "filter with composited descendants";

#if ENABLE(CSS_COMPOSITING)
    if (reasons.contains(CompositingReason::BlendingWithCompositedDescendants))
        return "blending with composited descendants";

    if (reasons.contains(CompositingReason::IsolatesCompositedBlendingDescendants))
        return "isolates composited blending descendants";
#endif

    if (reasons.contains(CompositingReason::Perspective))
        return "perspective";

    if (reasons.contains(CompositingReason::Preserve3D))
        return "preserve-3d";

    if (reasons.contains(CompositingReason::Root))
        return "root";

    return "";
}
#endif

// Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
// up to the enclosing compositing ancestor. This is required because compositing layers are parented
// according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
// Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
// but a sibling in the z-order hierarchy.
bool RenderLayerCompositor::clippedByAncestor(RenderLayer& layer) const
{
    if (!layer.isComposited() || !layer.parent())
        return false;

    auto* compositingAncestor = layer.ancestorCompositingLayer();
    if (!compositingAncestor)
        return false;

    // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
    // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
    // and layer. The exception is when the compositingAncestor isolates composited blending children,
    // in this case it is not allowed to clipsCompositingDescendants() and each of its children
    // will be clippedByAncestor()s, including the compositingAncestor.
    auto* computeClipRoot = compositingAncestor;
    if (!compositingAncestor->isolatesCompositedBlending()) {
        computeClipRoot = nullptr;
        auto* parent = &layer;
        while (parent) {
            auto* next = parent->parent();
            if (next == compositingAncestor) {
                computeClipRoot = parent;
                break;
            }
            parent = next;
        }

        if (!computeClipRoot || computeClipRoot == &layer)
            return false;
    }

    return !layer.backgroundClipRect(RenderLayer::ClipRectsContext(computeClipRoot, TemporaryClipRects)).isInfinite(); // FIXME: Incorrect for CSS regions.
}

// Return true if the given layer is a stacking context and has compositing child
// layers that it needs to clip. In this case we insert a clipping GraphicsLayer
// into the hierarchy between this layer and its children in the z-order hierarchy.
bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer& layer) const
{
    return layer.hasCompositingDescendant() && layer.renderer().hasClipOrOverflowClip() && !layer.isolatesCompositedBlending();
}

bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const
{
    if (isMainFrameCompositor())
        return false;

#if PLATFORM(MAC) || PLATFORM(IOS)
    if (!m_renderView.settings().asyncFrameScrollingEnabled())
        return false;
#endif

    if (!(m_compositingTriggers & ChromeClient::ScrollableNonMainFrameTrigger))
        return false;

    // Need this done first to determine overflow.
    ASSERT(!m_renderView.needsLayout());
    return m_renderView.frameView().isScrollable();
}

bool RenderLayerCompositor::requiresCompositingForTransform(RenderLayerModelObject& renderer) const
{
    if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
        return false;

    // Note that we ask the renderer if it has a transform, because the style may have transforms,
    // but the renderer may be an inline that doesn't suppport them.
    return renderer.hasTransform() && renderer.style().transform().has3DOperation();
}

bool RenderLayerCompositor::requiresCompositingForBackfaceVisibility(RenderLayerModelObject& renderer) const
{
    if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
        return false;

    if (renderer.style().backfaceVisibility() != BackfaceVisibilityHidden)
        return false;
        
    if (renderer.layer()->has3DTransformedAncestor())
        return true;
    
    // FIXME: workaround for webkit.org/b/132801
    auto* stackingContext = renderer.layer()->stackingContainer();
    if (stackingContext && stackingContext->renderer().style().transformStyle3D() == TransformStyle3DPreserve3D)
        return true;

    return false;
}

bool RenderLayerCompositor::requiresCompositingForVideo(RenderLayerModelObject& renderer) const
{
    if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
        return false;
#if ENABLE(VIDEO)
    if (is<RenderVideo>(renderer)) {
        auto& video = downcast<RenderVideo>(renderer);
        return (video.requiresImmediateCompositing() || video.shouldDisplayVideo()) && canAccelerateVideoRendering(video);
    }
#else
    UNUSED_PARAM(renderer);
#endif
    return false;
}

bool RenderLayerCompositor::requiresCompositingForCanvas(RenderLayerModelObject& renderer) const
{
    if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
        return false;

    if (renderer.isCanvas()) {
#if USE(COMPOSITING_FOR_SMALL_CANVASES)
        bool isCanvasLargeEnoughToForceCompositing = true;
#else
        auto* canvas = downcast<HTMLCanvasElement>(renderer.element());
        auto canvasArea = canvas->size().area<RecordOverflow>();
        bool isCanvasLargeEnoughToForceCompositing = !canvasArea.hasOverflowed() && canvasArea.unsafeGet() >= canvasAreaThresholdRequiringCompositing;
#endif
        CanvasCompositingStrategy compositingStrategy = canvasCompositingStrategy(renderer);
        return compositingStrategy == CanvasAsLayerContents || (compositingStrategy == CanvasPaintedToLayer && isCanvasLargeEnoughToForceCompositing);
    }

    return false;
}

bool RenderLayerCompositor::requiresCompositingForPlugin(RenderLayerModelObject& renderer) const
{
    if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
        return false;

    bool composite = is<RenderEmbeddedObject>(renderer) && downcast<RenderEmbeddedObject>(renderer).allowsAcceleratedCompositing();
    if (!composite)
        return false;

    m_reevaluateCompositingAfterLayout = true;
    
    auto& pluginRenderer = downcast<RenderWidget>(renderer);
    if (pluginRenderer.style().visibility() != VISIBLE)
        return false;

    // If we can't reliably know the size of the plugin yet, don't change compositing state.
    if (pluginRenderer.needsLayout())
        return pluginRenderer.isComposited();

    // Don't go into compositing mode if height or width are zero, or size is 1x1.
    IntRect contentBox = snappedIntRect(pluginRenderer.contentBoxRect());
    return contentBox.height() * contentBox.width() > 1;
}

bool RenderLayerCompositor::requiresCompositingForFrame(RenderLayerModelObject& renderer) const
{
    if (!is<RenderWidget>(renderer))
        return false;

    auto& frameRenderer = downcast<RenderWidget>(renderer);
    if (frameRenderer.style().visibility() != VISIBLE)
        return false;

    if (!frameRenderer.requiresAcceleratedCompositing())
        return false;

    m_reevaluateCompositingAfterLayout = true;

    // If we can't reliably know the size of the iframe yet, don't change compositing state.
    if (!frameRenderer.parent() || frameRenderer.needsLayout())
        return frameRenderer.isComposited();
    
    // Don't go into compositing mode if height or width are zero.
    return !snappedIntRect(frameRenderer.contentBoxRect()).isEmpty();
}

bool RenderLayerCompositor::requiresCompositingForAnimation(RenderLayerModelObject& renderer) const
{
    if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
        return false;

    if (auto* element = renderer.element()) {
        if (auto* timeline = element->document().existingTimeline()) {
            if (timeline->runningAnimationsForElementAreAllAccelerated(*element))
                return true;
        }
    }

    if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled())
        return false;

    const AnimationBase::RunningState activeAnimationState = AnimationBase::Running | AnimationBase::Paused;
    auto& animController = renderer.animation();
    return (animController.isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity, activeAnimationState)
            && (inCompositingMode() || (m_compositingTriggers & ChromeClient::AnimatedOpacityTrigger)))
            || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyFilter, activeAnimationState)
#if ENABLE(FILTERS_LEVEL_2)
            || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitBackdropFilter, activeAnimationState)
#endif
            || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyTransform, activeAnimationState);
}

bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderLayerModelObject& renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason& reason) const
{
    auto& layer = *downcast<RenderBoxModelObject>(renderer).layer();

    // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
    // via compositing so that they also apply to those composited descendants.
    if (hasCompositedDescendants && (layer.isolatesCompositedBlending() || layer.transform() || renderer.createsGroup() || renderer.hasReflection())) {
        reason = RenderLayer::IndirectCompositingReason::GraphicalEffect;
        return true;
    }

    // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that
    // will be affected by the preserve-3d or perspective.
    if (has3DTransformedDescendants) {
        if (renderer.style().transformStyle3D() == TransformStyle3DPreserve3D) {
            reason = RenderLayer::IndirectCompositingReason::Preserve3D;
            return true;
        }
    
        if (renderer.style().hasPerspective()) {
            reason = RenderLayer::IndirectCompositingReason::Perspective;
            return true;
        }
    }

    reason = RenderLayer::IndirectCompositingReason::None;
    return false;
}

bool RenderLayerCompositor::styleChangeMayAffectIndirectCompositingReasons(const RenderLayerModelObject& renderer, const RenderStyle& oldStyle)
{
    auto& style = renderer.style();
    if (RenderElement::createsGroupForStyle(style) != RenderElement::createsGroupForStyle(oldStyle))
        return true;
    if (style.isolation() != oldStyle.isolation())
        return true;
    if (style.hasTransform() != oldStyle.hasTransform())
        return true;
    if (style.boxReflect() != oldStyle.boxReflect())
        return true;
    if (style.transformStyle3D() != oldStyle.transformStyle3D())
        return true;
    if (style.hasPerspective() != oldStyle.hasPerspective())
        return true;

    return false;
}

bool RenderLayerCompositor::requiresCompositingForFilters(RenderLayerModelObject& renderer) const
{
#if ENABLE(FILTERS_LEVEL_2)
    if (renderer.hasBackdropFilter())
        return true;
#endif

    if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
        return false;

    return renderer.hasFilter();
}

bool RenderLayerCompositor::requiresCompositingForWillChange(RenderLayerModelObject& renderer) const
{
    if (!renderer.style().willChange() || !renderer.style().willChange()->canTriggerCompositing())
        return false;

    if (is<RenderBox>(renderer))
        return true;

    return renderer.style().willChange()->canTriggerCompositingOnInline();
}

bool RenderLayerCompositor::isAsyncScrollableStickyLayer(const RenderLayer& layer, const RenderLayer** enclosingAcceleratedOverflowLayer) const
{
    ASSERT(layer.renderer().isStickilyPositioned());

    auto* enclosingOverflowLayer = layer.enclosingOverflowClipLayer(ExcludeSelf);

#if PLATFORM(IOS)
    if (enclosingOverflowLayer && enclosingOverflowLayer->hasTouchScrollableOverflow()) {
        if (enclosingAcceleratedOverflowLayer)
            *enclosingAcceleratedOverflowLayer = enclosingOverflowLayer;
        return true;
    }
#else
    UNUSED_PARAM(enclosingAcceleratedOverflowLayer);
#endif
    // If the layer is inside normal overflow, it's not async-scrollable.
    if (enclosingOverflowLayer)
        return false;

    // No overflow ancestor, so see if the frame supports async scrolling.
    if (hasCoordinatedScrolling())
        return true;

#if PLATFORM(IOS)
    // iOS WK1 has fixed/sticky support in the main frame via WebFixedPositionContent.
    return isMainFrameCompositor();
#else
    return false;
#endif
}

bool RenderLayerCompositor::isViewportConstrainedFixedOrStickyLayer(const RenderLayer& layer) const
{
    if (layer.renderer().isStickilyPositioned())
        return isAsyncScrollableStickyLayer(layer);

    if (layer.renderer().style().position() != FixedPosition)
        return false;

    // FIXME: Handle fixed inside of a transform, which should not behave as fixed.
    for (auto* stackingContainer = layer.stackingContainer(); stackingContainer; stackingContainer = stackingContainer->stackingContainer()) {
        if (stackingContainer->isComposited() && stackingContainer->renderer().isFixedPositioned())
            return false;
    }

    return true;
}

bool RenderLayerCompositor::useCoordinatedScrollingForLayer(const RenderLayer& layer) const
{
    if (layer.isRenderViewLayer() && hasCoordinatedScrolling())
        return true;

    return layer.usesAcceleratedScrolling();
}

bool RenderLayerCompositor::requiresCompositingForPosition(RenderLayerModelObject& renderer, const RenderLayer& layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
{
    // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
    // opacity, transform) can get their own composited layer. A stacking context is required otherwise
    // z-index and clipping will be broken.
    if (!renderer.isPositioned())
        return false;
    
    EPosition position = renderer.style().position();
    bool isFixed = renderer.isOutOfFlowPositioned() && position == FixedPosition;
    if (isFixed && !layer.isStackingContainer())
        return false;
    
    bool isSticky = renderer.isInFlowPositioned() && position == StickyPosition;
    if (!isFixed && !isSticky)
        return false;

    // FIXME: acceleratedCompositingForFixedPositionEnabled should probably be renamed acceleratedCompositingForViewportConstrainedPositionEnabled().
    if (!m_renderView.settings().acceleratedCompositingForFixedPositionEnabled())
        return false;

    if (isSticky)
        return isAsyncScrollableStickyLayer(layer);

    auto container = renderer.container();
    // If the renderer is not hooked up yet then we have to wait until it is.
    if (!container) {
        m_reevaluateCompositingAfterLayout = true;
        return false;
    }

    // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements.
    // They will stay fixed wrt the container rather than the enclosing frame.
    if (container != &m_renderView) {
        if (viewportConstrainedNotCompositedReason)
            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNonViewContainer;
        return false;
    }
    
    // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done.
    if (!m_inPostLayoutUpdate) {
        m_reevaluateCompositingAfterLayout = true;
        return layer.isComposited();
    }

    bool paintsContent = layer.isVisuallyNonEmpty() || layer.hasVisibleDescendant();
    if (!paintsContent) {
        if (viewportConstrainedNotCompositedReason)
            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNoVisibleContent;
        return false;
    }

    // Fixed position elements that are invisible in the current view don't get their own layer.
    // FIXME: We shouldn't have to check useFixedLayout() here; one of the viewport rects needs to give the correct answer.
    LayoutRect viewBounds;
    if (m_renderView.frameView().useFixedLayout())
        viewBounds = m_renderView.unscaledDocumentRect();
    else
        viewBounds = m_renderView.frameView().rectForFixedPositionLayout();

    LayoutRect layerBounds = layer.calculateLayerBounds(&layer, LayoutSize(), RenderLayer::UseLocalClipRectIfPossible | RenderLayer::IncludeLayerFilterOutsets | RenderLayer::UseFragmentBoxesExcludingCompositing
        | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask | RenderLayer::IncludeCompositedDescendants);
    // Map to m_renderView to ignore page scale.
    FloatRect absoluteBounds = layer.renderer().localToContainerQuad(FloatRect(layerBounds), &m_renderView).boundingBox();
    if (!viewBounds.intersects(enclosingIntRect(absoluteBounds))) {
        if (viewportConstrainedNotCompositedReason)
            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView;
        LOG_WITH_STREAM(Compositing, stream << "Layer " << &layer << " bounds " << absoluteBounds << " outside visible rect " << viewBounds);
        return false;
    }
    
    return true;
}

bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const RenderLayer& layer) const
{
    return layer.needsCompositedScrolling();
}

#if PLATFORM(IOS)
bool RenderLayerCompositor::requiresCompositingForScrolling(const RenderLayer& layer) const
{
    if (!layer.hasAcceleratedTouchScrolling())
        return false;

    if (!m_inPostLayoutUpdate) {
        m_reevaluateCompositingAfterLayout = true;
        return layer.isComposited();
    }

    return layer.hasTouchScrollableOverflow();
}
#endif

bool RenderLayerCompositor::isRunningTransformAnimation(RenderLayerModelObject& renderer) const
{
    if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
        return false;

    if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) {
        if (auto* element = renderer.element()) {
            if (auto* timeline = element->document().existingTimeline())
                return timeline->isRunningAnimationOnRenderer(renderer, CSSPropertyTransform);
        }
        return false;
    }
    return renderer.animation().isRunningAnimationOnRenderer(renderer, CSSPropertyTransform, AnimationBase::Running | AnimationBase::Paused);
}

// If an element has negative z-index children, those children render in front of the 
// layer background, so we need an extra 'contents' layer for the foreground of the layer
// object.
bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer& layer) const
{
    return layer.hasNegativeZOrderList();
}

bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const
{
    auto& frameView = m_renderView.frameView();

    // This applies when the application UI handles scrolling, in which case RenderLayerCompositor doesn't need to manage it.
    if (frameView.delegatesScrolling() && isMainFrameCompositor())
        return false;

    // We need to handle our own scrolling if we're:
    return !m_renderView.frameView().platformWidget() // viewless (i.e. non-Mac, or Mac in WebKit2)
        || attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac
}

void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
{
    if (!scrollbar)
        return;

    context.save();
    const IntRect& scrollbarRect = scrollbar->frameRect();
    context.translate(-scrollbarRect.location());
    IntRect transformedClip = clip;
    transformedClip.moveBy(scrollbarRect.location());
    scrollbar->paint(context, transformedClip);
    context.restore();
}

void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const FloatRect& clip, GraphicsLayerPaintBehavior)
{
    IntRect pixelSnappedRectForIntegralPositionedItems = snappedIntRect(LayoutRect(clip));
    if (graphicsLayer == layerForHorizontalScrollbar())
        paintScrollbar(m_renderView.frameView().horizontalScrollbar(), context, pixelSnappedRectForIntegralPositionedItems);
    else if (graphicsLayer == layerForVerticalScrollbar())
        paintScrollbar(m_renderView.frameView().verticalScrollbar(), context, pixelSnappedRectForIntegralPositionedItems);
    else if (graphicsLayer == layerForScrollCorner()) {
        const IntRect& scrollCorner = m_renderView.frameView().scrollCornerRect();
        context.save();
        context.translate(-scrollCorner.location());
        IntRect transformedClip = pixelSnappedRectForIntegralPositionedItems;
        transformedClip.moveBy(scrollCorner.location());
        m_renderView.frameView().paintScrollCorner(context, transformedClip);
        context.restore();
    }
}

bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
{
    auto* renderViewBacking = m_renderView.layer()->backing();
    return renderViewBacking && renderViewBacking->isFrameLayerWithTiledBacking();
}

bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer& layer) const
{
    if (!layer.isRenderViewLayer())
        return false;

    if (m_renderView.settings().fixedBackgroundsPaintRelativeToDocument())
        return false;

    LOG(Compositing, "RenderLayerCompositor %p needsFixedRootBackgroundLayer returning %d", this, supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgroundIsEntirelyFixed());

    return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgroundIsEntirelyFixed();
}

GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const
{
    // Get the fixed root background from the RenderView layer's backing.
    auto* viewLayer = m_renderView.layer();
    if (!viewLayer)
        return nullptr;

    if (viewLayer->isComposited() && viewLayer->backing()->backgroundLayerPaintsFixedRootBackground())
        return viewLayer->backing()->backgroundLayer();

    return nullptr;
}

void RenderLayerCompositor::resetTrackedRepaintRects()
{
    if (auto* rootLayer = rootGraphicsLayer()) {
        GraphicsLayer::traverse(*rootLayer, [](GraphicsLayer& layer) {
            layer.resetTrackedRepaints();
        });
    }
}

float RenderLayerCompositor::deviceScaleFactor() const
{
    return m_renderView.document().deviceScaleFactor();
}

float RenderLayerCompositor::pageScaleFactor() const
{
    return page().pageScaleFactor();
}

float RenderLayerCompositor::zoomedOutPageScaleFactor() const
{
    return page().zoomedOutPageScaleFactor();
}

float RenderLayerCompositor::contentsScaleMultiplierForNewTiles(const GraphicsLayer*) const
{
#if PLATFORM(IOS)
    LegacyTileCache* tileCache = nullptr;
    if (auto* frameView = page().mainFrame().view())
        tileCache = frameView->legacyTileCache();

    if (!tileCache)
        return 1;

    return tileCache->tileControllerShouldUseLowScaleTiles() ? 0.125 : 1;
#else
    return 1;
#endif
}

void RenderLayerCompositor::didCommitChangesForLayer(const GraphicsLayer*) const
{
    // Nothing to do here yet.
}

bool RenderLayerCompositor::documentUsesTiledBacking() const
{
    auto* layer = m_renderView.layer();
    if (!layer)
        return false;

    auto* backing = layer->backing();
    if (!backing)
        return false;

    return backing->isFrameLayerWithTiledBacking();
}

bool RenderLayerCompositor::isMainFrameCompositor() const
{
    return m_renderView.frameView().frame().isMainFrame();
}

bool RenderLayerCompositor::shouldCompositeOverflowControls() const
{
    auto& frameView = m_renderView.frameView();

    if (frameView.platformWidget())
        return false;

    if (frameView.delegatesScrolling())
        return false;

    if (documentUsesTiledBacking())
        return true;

    if (m_overflowControlsHostLayer && isMainFrameCompositor())
        return true;

#if !USE(COORDINATED_GRAPHICS_THREADED)
    if (!frameView.hasOverlayScrollbars())
        return false;
#endif

    return true;
}

bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
{
    return shouldCompositeOverflowControls() && m_renderView.frameView().horizontalScrollbar();
}

bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
{
    return shouldCompositeOverflowControls() && m_renderView.frameView().verticalScrollbar();
}

bool RenderLayerCompositor::requiresScrollCornerLayer() const
{
    return shouldCompositeOverflowControls() && m_renderView.frameView().isScrollCornerVisible();
}

#if ENABLE(RUBBER_BANDING)
bool RenderLayerCompositor::requiresOverhangAreasLayer() const
{
    if (!isMainFrameCompositor())
        return false;

    // We do want a layer if we're using tiled drawing and can scroll.
    if (documentUsesTiledBacking() && m_renderView.frameView().hasOpaqueBackground() && !m_renderView.frameView().prohibitsScrolling())
        return true;

    return false;
}

bool RenderLayerCompositor::requiresContentShadowLayer() const
{
    if (!isMainFrameCompositor())
        return false;

#if PLATFORM(COCOA)
    if (viewHasTransparentBackground())
        return false;

    // If the background is going to extend, then it doesn't make sense to have a shadow layer.
    if (m_renderView.settings().backgroundShouldExtendBeyondPage())
        return false;

    // On Mac, we want a content shadow layer if we're using tiled drawing and can scroll.
    if (documentUsesTiledBacking() && !m_renderView.frameView().prohibitsScrolling())
        return true;
#endif

    return false;
}

GraphicsLayer* RenderLayerCompositor::updateLayerForTopOverhangArea(bool wantsLayer)
{
    if (!isMainFrameCompositor())
        return nullptr;

    if (!wantsLayer) {
        if (m_layerForTopOverhangArea) {
            m_layerForTopOverhangArea->removeFromParent();
            m_layerForTopOverhangArea = nullptr;
        }
        return nullptr;
    }

    if (!m_layerForTopOverhangArea) {
        m_layerForTopOverhangArea = GraphicsLayer::create(graphicsLayerFactory(), *this);
        m_layerForTopOverhangArea->setName("top overhang");
        m_scrollLayer->addChildBelow(m_layerForTopOverhangArea.get(), m_rootContentLayer.get());
    }

    return m_layerForTopOverhangArea.get();
}

GraphicsLayer* RenderLayerCompositor::updateLayerForBottomOverhangArea(bool wantsLayer)
{
    if (!isMainFrameCompositor())
        return nullptr;

    if (!wantsLayer) {
        if (m_layerForBottomOverhangArea) {
            m_layerForBottomOverhangArea->removeFromParent();
            m_layerForBottomOverhangArea = nullptr;
        }
        return nullptr;
    }

    if (!m_layerForBottomOverhangArea) {
        m_layerForBottomOverhangArea = GraphicsLayer::create(graphicsLayerFactory(), *this);
        m_layerForBottomOverhangArea->setName("bottom overhang");
        m_scrollLayer->addChildBelow(m_layerForBottomOverhangArea.get(), m_rootContentLayer.get());
    }

    m_layerForBottomOverhangArea->setPosition(FloatPoint(0, m_rootContentLayer->size().height() + m_renderView.frameView().headerHeight()
        + m_renderView.frameView().footerHeight() + m_renderView.frameView().topContentInset()));
    return m_layerForBottomOverhangArea.get();
}

GraphicsLayer* RenderLayerCompositor::updateLayerForHeader(bool wantsLayer)
{
    if (!isMainFrameCompositor())
        return nullptr;

    if (!wantsLayer) {
        if (m_layerForHeader) {
            m_layerForHeader->removeFromParent();
            m_layerForHeader = nullptr;

            // The ScrollingTree knows about the header layer, and the position of the root layer is affected
            // by the header layer, so if we remove the header, we need to tell the scrolling tree.
            if (auto* scrollingCoordinator = this->scrollingCoordinator())
                scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());
        }
        return nullptr;
    }

    if (!m_layerForHeader) {
        m_layerForHeader = GraphicsLayer::create(graphicsLayerFactory(), *this);
        m_layerForHeader->setName("header");
        m_scrollLayer->addChildAbove(m_layerForHeader.get(), m_rootContentLayer.get());
        m_renderView.frameView().addPaintPendingMilestones(DidFirstFlushForHeaderLayer);
    }

    m_layerForHeader->setPosition(FloatPoint(0,
        FrameView::yPositionForHeaderLayer(m_renderView.frameView().scrollPosition(), m_renderView.frameView().topContentInset())));
    m_layerForHeader->setAnchorPoint(FloatPoint3D());
    m_layerForHeader->setSize(FloatSize(m_renderView.frameView().visibleWidth(), m_renderView.frameView().headerHeight()));

    if (auto* scrollingCoordinator = this->scrollingCoordinator())
        scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());

    page().chrome().client().didAddHeaderLayer(*m_layerForHeader);

    return m_layerForHeader.get();
}

GraphicsLayer* RenderLayerCompositor::updateLayerForFooter(bool wantsLayer)
{
    if (!isMainFrameCompositor())
        return nullptr;

    if (!wantsLayer) {
        if (m_layerForFooter) {
            m_layerForFooter->removeFromParent();
            m_layerForFooter = nullptr;

            // The ScrollingTree knows about the footer layer, and the total scrollable size is affected
            // by the footer layer, so if we remove the footer, we need to tell the scrolling tree.
            if (auto* scrollingCoordinator = this->scrollingCoordinator())
                scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());
        }
        return nullptr;
    }

    if (!m_layerForFooter) {
        m_layerForFooter = GraphicsLayer::create(graphicsLayerFactory(), *this);
        m_layerForFooter->setName("footer");
        m_scrollLayer->addChildAbove(m_layerForFooter.get(), m_rootContentLayer.get());
    }

    float totalContentHeight = m_rootContentLayer->size().height() + m_renderView.frameView().headerHeight() + m_renderView.frameView().footerHeight();
    m_layerForFooter->setPosition(FloatPoint(0, FrameView::yPositionForFooterLayer(m_renderView.frameView().scrollPosition(),
        m_renderView.frameView().topContentInset(), totalContentHeight, m_renderView.frameView().footerHeight())));
    m_layerForFooter->setAnchorPoint(FloatPoint3D());
    m_layerForFooter->setSize(FloatSize(m_renderView.frameView().visibleWidth(), m_renderView.frameView().footerHeight()));

    if (auto* scrollingCoordinator = this->scrollingCoordinator())
        scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());

    page().chrome().client().didAddFooterLayer(*m_layerForFooter);

    return m_layerForFooter.get();
}

#endif

bool RenderLayerCompositor::viewHasTransparentBackground(Color* backgroundColor) const
{
    if (m_renderView.frameView().isTransparent()) {
        if (backgroundColor)
            *backgroundColor = Color(); // Return an invalid color.
        return true;
    }

    Color documentBackgroundColor = m_renderView.frameView().documentBackgroundColor();
    if (!documentBackgroundColor.isValid())
        documentBackgroundColor = Color::white;

    if (backgroundColor)
        *backgroundColor = documentBackgroundColor;
        
    return !documentBackgroundColor.isOpaque();
}

// We can't rely on getting layerStyleChanged() for a style change that affects the root background, because the style change may
// be on the body which has no RenderLayer.
void RenderLayerCompositor::rootOrBodyStyleChanged(RenderElement& renderer, const RenderStyle* oldStyle)
{
    if (!inCompositingMode())
        return;

    Color oldBackgroundColor;
    if (oldStyle)
        oldBackgroundColor = oldStyle->visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);

    if (oldBackgroundColor != renderer.style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor))
        rootBackgroundTransparencyChanged();

    bool hadFixedBackground = oldStyle && oldStyle->hasEntirelyFixedBackground();
    if (hadFixedBackground != renderer.style().hasEntirelyFixedBackground()) {
        setCompositingLayersNeedRebuild();
        scheduleCompositingLayerUpdate();
    }
}

void RenderLayerCompositor::rootBackgroundTransparencyChanged()
{
    if (!inCompositingMode())
        return;

    bool isTransparent = viewHasTransparentBackground();

    LOG(Compositing, "RenderLayerCompositor %p rootBackgroundTransparencyChanged. isTransparent=%d, changed=%d", this, isTransparent, m_viewBackgroundIsTransparent == isTransparent);
    if (m_viewBackgroundIsTransparent == isTransparent)
        return;

    m_viewBackgroundIsTransparent = isTransparent;

    // FIXME: We should do something less expensive than a full layer rebuild.
    setCompositingLayersNeedRebuild();
    scheduleCompositingLayerUpdate();
}

void RenderLayerCompositor::setRootExtendedBackgroundColor(const Color& color)
{
    if (color == m_rootExtendedBackgroundColor)
        return;

    m_rootExtendedBackgroundColor = color;

    page().chrome().client().pageExtendedBackgroundColorDidChange(color);

#if ENABLE(RUBBER_BANDING)
    if (!m_layerForOverhangAreas)
        return;

    m_layerForOverhangAreas->setBackgroundColor(m_rootExtendedBackgroundColor);

    if (!m_rootExtendedBackgroundColor.isValid())
        m_layerForOverhangAreas->setCustomAppearance(GraphicsLayer::ScrollingOverhang);
#endif
}

void RenderLayerCompositor::updateOverflowControlsLayers()
{
#if ENABLE(RUBBER_BANDING)
    if (requiresOverhangAreasLayer()) {
        if (!m_layerForOverhangAreas) {
            m_layerForOverhangAreas = GraphicsLayer::create(graphicsLayerFactory(), *this);
            m_layerForOverhangAreas->setName("overhang areas");
            m_layerForOverhangAreas->setDrawsContent(false);

            float topContentInset = m_renderView.frameView().topContentInset();
            IntSize overhangAreaSize = m_renderView.frameView().frameRect().size();
            overhangAreaSize.setHeight(overhangAreaSize.height() - topContentInset);
            m_layerForOverhangAreas->setSize(overhangAreaSize);
            m_layerForOverhangAreas->setPosition(FloatPoint(0, topContentInset));
            m_layerForOverhangAreas->setAnchorPoint(FloatPoint3D());

            if (m_renderView.settings().backgroundShouldExtendBeyondPage())
                m_layerForOverhangAreas->setBackgroundColor(m_renderView.frameView().documentBackgroundColor());
            else
                m_layerForOverhangAreas->setCustomAppearance(GraphicsLayer::ScrollingOverhang);

            // We want the overhang areas layer to be positioned below the frame contents,
            // so insert it below the clip layer.
            m_overflowControlsHostLayer->addChildBelow(m_layerForOverhangAreas.get(), m_clipLayer.get());
        }
    } else if (m_layerForOverhangAreas) {
        m_layerForOverhangAreas->removeFromParent();
        m_layerForOverhangAreas = nullptr;
    }

    if (requiresContentShadowLayer()) {
        if (!m_contentShadowLayer) {
            m_contentShadowLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
            m_contentShadowLayer->setName("content shadow");
            m_contentShadowLayer->setSize(m_rootContentLayer->size());
            m_contentShadowLayer->setPosition(m_rootContentLayer->position());
            m_contentShadowLayer->setAnchorPoint(FloatPoint3D());
            m_contentShadowLayer->setCustomAppearance(GraphicsLayer::ScrollingShadow);

            m_scrollLayer->addChildBelow(m_contentShadowLayer.get(), m_rootContentLayer.get());
        }
    } else if (m_contentShadowLayer) {
        m_contentShadowLayer->removeFromParent();
        m_contentShadowLayer = nullptr;
    }
#endif

    if (requiresHorizontalScrollbarLayer()) {
        if (!m_layerForHorizontalScrollbar) {
            m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), *this);
            m_layerForHorizontalScrollbar->setCanDetachBackingStore(false);
            m_layerForHorizontalScrollbar->setShowDebugBorder(m_showDebugBorders);
            m_layerForHorizontalScrollbar->setName("horizontal scrollbar container");
#if PLATFORM(COCOA) && USE(CA)
            m_layerForHorizontalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
#endif
            m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());

            if (auto* scrollingCoordinator = this->scrollingCoordinator())
                scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
        }
    } else if (m_layerForHorizontalScrollbar) {
        m_layerForHorizontalScrollbar->removeFromParent();
        m_layerForHorizontalScrollbar = nullptr;

        if (auto* scrollingCoordinator = this->scrollingCoordinator())
            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
    }

    if (requiresVerticalScrollbarLayer()) {
        if (!m_layerForVerticalScrollbar) {
            m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), *this);
            m_layerForVerticalScrollbar->setCanDetachBackingStore(false);
            m_layerForVerticalScrollbar->setShowDebugBorder(m_showDebugBorders);
            m_layerForVerticalScrollbar->setName("vertical scrollbar container");
#if PLATFORM(COCOA) && USE(CA)
            m_layerForVerticalScrollbar->setAcceleratesDrawing(acceleratedDrawingEnabled());
#endif
            m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());

            if (auto* scrollingCoordinator = this->scrollingCoordinator())
                scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
        }
    } else if (m_layerForVerticalScrollbar) {
        m_layerForVerticalScrollbar->removeFromParent();
        m_layerForVerticalScrollbar = nullptr;

        if (auto* scrollingCoordinator = this->scrollingCoordinator())
            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
    }

    if (requiresScrollCornerLayer()) {
        if (!m_layerForScrollCorner) {
            m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), *this);
            m_layerForScrollCorner->setCanDetachBackingStore(false);
            m_layerForScrollCorner->setShowDebugBorder(m_showDebugBorders);
            m_layerForScrollCorner->setName("scroll corner");
#if PLATFORM(COCOA) && USE(CA)
            m_layerForScrollCorner->setAcceleratesDrawing(acceleratedDrawingEnabled());
#endif
            m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
        }
    } else if (m_layerForScrollCorner) {
        m_layerForScrollCorner->removeFromParent();
        m_layerForScrollCorner = nullptr;
    }

    m_renderView.frameView().positionScrollbarLayers();
}

void RenderLayerCompositor::ensureRootLayer()
{
    RootLayerAttachment expectedAttachment = isMainFrameCompositor() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
    if (expectedAttachment == m_rootLayerAttachment)
         return;

    if (!m_rootContentLayer) {
        m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
        m_rootContentLayer->setName("content root");
        IntRect overflowRect = snappedIntRect(m_renderView.layoutOverflowRect());
        m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
        m_rootContentLayer->setPosition(FloatPoint());

#if PLATFORM(IOS)
        // Page scale is applied above this on iOS, so we'll just say that our root layer applies it.
        auto& frame = m_renderView.frameView().frame();
        if (frame.isMainFrame())
            m_rootContentLayer->setAppliesPageScale();
#endif

        // Need to clip to prevent transformed content showing outside this frame
        updateRootContentLayerClipping();
    }

    if (requiresScrollLayer(expectedAttachment)) {
        if (!m_overflowControlsHostLayer) {
            ASSERT(!m_scrollLayer);
            ASSERT(!m_clipLayer);

            // Create a layer to host the clipping layer and the overflow controls layers.
            m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
            m_overflowControlsHostLayer->setName("overflow controls host");

            // Create a clipping layer if this is an iframe
            m_clipLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
            m_clipLayer->setName("frame clipping");
            m_clipLayer->setMasksToBounds(true);
            
            m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
            m_scrollLayer->setName("frame scrolling");

            // Hook them up
            m_overflowControlsHostLayer->addChild(m_clipLayer.get());
            m_clipLayer->addChild(m_scrollLayer.get());
            m_scrollLayer->addChild(m_rootContentLayer.get());

            m_clipLayer->setSize(m_renderView.frameView().sizeForVisibleContent());
            m_clipLayer->setPosition(positionForClipLayer());
            m_clipLayer->setAnchorPoint(FloatPoint3D());

            updateOverflowControlsLayers();

            if (hasCoordinatedScrolling())
                scheduleLayerFlush(true);
            else
                updateScrollLayerPosition();
        }
    } else {
        if (m_overflowControlsHostLayer) {
            m_overflowControlsHostLayer = nullptr;
            m_clipLayer = nullptr;
            m_scrollLayer = nullptr;
        }
    }

    // Check to see if we have to change the attachment
    if (m_rootLayerAttachment != RootLayerUnattached)
        detachRootLayer();

    attachRootLayer(expectedAttachment);
}

void RenderLayerCompositor::destroyRootLayer()
{
    if (!m_rootContentLayer)
        return;

    detachRootLayer();

#if ENABLE(RUBBER_BANDING)
    if (m_layerForOverhangAreas) {
        m_layerForOverhangAreas->removeFromParent();
        m_layerForOverhangAreas = nullptr;
    }
#endif

    if (m_layerForHorizontalScrollbar) {
        m_layerForHorizontalScrollbar->removeFromParent();
        m_layerForHorizontalScrollbar = nullptr;
        if (auto* scrollingCoordinator = this->scrollingCoordinator())
            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
        if (auto* horizontalScrollbar = m_renderView.frameView().verticalScrollbar())
            m_renderView.frameView().invalidateScrollbar(*horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
    }

    if (m_layerForVerticalScrollbar) {
        m_layerForVerticalScrollbar->removeFromParent();
        m_layerForVerticalScrollbar = nullptr;
        if (auto* scrollingCoordinator = this->scrollingCoordinator())
            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
        if (auto* verticalScrollbar = m_renderView.frameView().verticalScrollbar())
            m_renderView.frameView().invalidateScrollbar(*verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
    }

    if (m_layerForScrollCorner) {
        m_layerForScrollCorner = nullptr;
        m_renderView.frameView().invalidateScrollCorner(m_renderView.frameView().scrollCornerRect());
    }

    if (m_overflowControlsHostLayer) {
        m_overflowControlsHostLayer = nullptr;
        m_clipLayer = nullptr;
        m_scrollLayer = nullptr;
    }
    ASSERT(!m_scrollLayer);
    m_rootContentLayer = nullptr;

    m_layerUpdater = nullptr;
}

void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
{
    if (!m_rootContentLayer)
        return;

    LOG(Compositing, "RenderLayerCompositor %p attachRootLayer %d", this, attachment);

    switch (attachment) {
        case RootLayerUnattached:
            ASSERT_NOT_REACHED();
            break;
        case RootLayerAttachedViaChromeClient: {
            auto& frame = m_renderView.frameView().frame();
            page().chrome().client().attachRootGraphicsLayer(frame, rootGraphicsLayer());
            if (frame.isMainFrame())
                page().chrome().client().attachViewOverlayGraphicsLayer(frame, &page().pageOverlayController().layerWithViewOverlays());
            break;
        }
        case RootLayerAttachedViaEnclosingFrame: {
            // The layer will get hooked up via RenderLayerBacking::updateConfiguration()
            // for the frame's renderer in the parent document.
            if (auto* ownerElement = m_renderView.document().ownerElement())
                ownerElement->scheduleInvalidateStyleAndLayerComposition();
            break;
        }
    }

    m_rootLayerAttachment = attachment;
    rootLayerAttachmentChanged();
    
    if (m_shouldFlushOnReattach) {
        scheduleLayerFlushNow();
        m_shouldFlushOnReattach = false;
    }
}

void RenderLayerCompositor::detachRootLayer()
{
    if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
        return;

    switch (m_rootLayerAttachment) {
    case RootLayerAttachedViaEnclosingFrame: {
        // The layer will get unhooked up via RenderLayerBacking::updateGraphicsLayerConfiguration()
        // for the frame's renderer in the parent document.
        if (m_overflowControlsHostLayer)
            m_overflowControlsHostLayer->removeFromParent();
        else
            m_rootContentLayer->removeFromParent();

        if (auto* ownerElement = m_renderView.document().ownerElement())
            ownerElement->scheduleInvalidateStyleAndLayerComposition();
        break;
    }
    case RootLayerAttachedViaChromeClient: {
        auto& frame = m_renderView.frameView().frame();
        page().chrome().client().attachRootGraphicsLayer(frame, nullptr);
        if (frame.isMainFrame()) {
            page().chrome().client().attachViewOverlayGraphicsLayer(frame, nullptr);
            page().pageOverlayController().willDetachRootLayer();
        }
    }
    break;
    case RootLayerUnattached:
        break;
    }

    m_rootLayerAttachment = RootLayerUnattached;
    rootLayerAttachmentChanged();
}

void RenderLayerCompositor::updateRootLayerAttachment()
{
    ensureRootLayer();
}

void RenderLayerCompositor::rootLayerAttachmentChanged()
{
    // The document-relative page overlay layer (which is pinned to the main frame's layer tree)
    // is moved between different RenderLayerCompositors' layer trees, and needs to be
    // reattached whenever we swap in a new RenderLayerCompositor.
    if (m_rootLayerAttachment == RootLayerUnattached)
        return;

    auto& frame = m_renderView.frameView().frame();

    // The attachment can affect whether the RenderView layer's paintsIntoWindow() behavior,
    // so call updateDrawsContent() to update that.
    auto* layer = m_renderView.layer();
    if (auto* backing = layer ? layer->backing() : nullptr)
        backing->updateDrawsContent();

    if (!frame.isMainFrame())
        return;

    m_rootContentLayer->addChild(&page().pageOverlayController().layerWithDocumentOverlays());
}

void RenderLayerCompositor::notifyIFramesOfCompositingChange()
{
    // Compositing affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
    // we need to schedule a style recalc in our parent document.
    if (auto* ownerElement = m_renderView.document().ownerElement())
        ownerElement->scheduleInvalidateStyleAndLayerComposition();
}

bool RenderLayerCompositor::layerHas3DContent(const RenderLayer& layer) const
{
    const RenderStyle& style = layer.renderer().style();

    if (style.transformStyle3D() == TransformStyle3DPreserve3D || style.hasPerspective() || style.transform().has3DOperation())
        return true;

    const_cast<RenderLayer&>(layer).updateLayerListsIfNeeded();

#if !ASSERT_DISABLED
    LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(&layer));
#endif

    if (auto* negZOrderList = layer.negZOrderList()) {
        for (auto* renderLayer : *negZOrderList) {
            if (layerHas3DContent(*renderLayer))
                return true;
        }
    }

    if (auto* posZOrderList = layer.posZOrderList()) {
        for (auto* renderLayer : *posZOrderList) {
            if (layerHas3DContent(*renderLayer))
                return true;
        }
    }

    if (auto* normalFlowList = layer.normalFlowList()) {
        for (auto* renderLayer : *normalFlowList) {
            if (layerHas3DContent(*renderLayer))
                return true;
        }
    }

    return false;
}

void RenderLayerCompositor::deviceOrPageScaleFactorChanged()
{
    // Page scale will only be applied at to the RenderView and sublayers, but the device scale factor
    // needs to be applied at the level of rootGraphicsLayer().
    if (auto* rootLayer = rootGraphicsLayer())
        rootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
}

static bool canCoordinateScrollingForLayer(const RenderLayer& layer)
{
    return (layer.isRenderViewLayer() || layer.parent()) && layer.isComposited();
}

void RenderLayerCompositor::updateScrollCoordinatedStatus(RenderLayer& layer, OptionSet<ScrollingNodeChangeFlags> changes)
{
    LayerScrollCoordinationRoles coordinationRoles = 0;
    if (isViewportConstrainedFixedOrStickyLayer(layer))
        coordinationRoles |= ViewportConstrained;

    if (useCoordinatedScrollingForLayer(layer))
        coordinationRoles |= Scrolling;

    if (layer.isComposited())
        layer.backing()->setIsScrollCoordinatedWithViewportConstrainedRole(coordinationRoles & ViewportConstrained);

    if (coordinationRoles && canCoordinateScrollingForLayer(layer)) {
        if (m_scrollCoordinatedLayers.add(&layer).isNewEntry)
            m_subframeScrollLayersNeedReattach = true;

        updateScrollCoordinatedLayer(layer, coordinationRoles, changes);
    } else
        removeFromScrollCoordinatedLayers(layer);
}

void RenderLayerCompositor::removeFromScrollCoordinatedLayers(RenderLayer& layer)
{
    if (!m_scrollCoordinatedLayers.contains(&layer))
        return;

    m_subframeScrollLayersNeedReattach = true;
    
    m_scrollCoordinatedLayers.remove(&layer);
    m_scrollCoordinatedLayersNeedingUpdate.remove(&layer);

    detachScrollCoordinatedLayer(layer, Scrolling | ViewportConstrained);
}

FixedPositionViewportConstraints RenderLayerCompositor::computeFixedViewportConstraints(RenderLayer& layer) const
{
    ASSERT(layer.isComposited());

    auto* graphicsLayer = layer.backing()->graphicsLayer();

    FixedPositionViewportConstraints constraints;
    constraints.setLayerPositionAtLastLayout(graphicsLayer->position());
    constraints.setViewportRectAtLastLayout(m_renderView.frameView().rectForFixedPositionLayout());
    constraints.setAlignmentOffset(graphicsLayer->pixelAlignmentOffset());

    const RenderStyle& style = layer.renderer().style();
    if (!style.left().isAuto())
        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);

    if (!style.right().isAuto())
        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight);

    if (!style.top().isAuto())
        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);

    if (!style.bottom().isAuto())
        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom);

    // If left and right are auto, use left.
    if (style.left().isAuto() && style.right().isAuto())
        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);

    // If top and bottom are auto, use top.
    if (style.top().isAuto() && style.bottom().isAuto())
        constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
        
    return constraints;
}

StickyPositionViewportConstraints RenderLayerCompositor::computeStickyViewportConstraints(RenderLayer& layer) const
{
    ASSERT(layer.isComposited());
#if !PLATFORM(IOS)
    // We should never get here for stickies constrained by an enclosing clipping layer.
    // FIXME: Why does this assertion fail on iOS?
    ASSERT(!layer.enclosingOverflowClipLayer(ExcludeSelf));
#endif

    auto& renderer = downcast<RenderBoxModelObject>(layer.renderer());

    StickyPositionViewportConstraints constraints;
    renderer.computeStickyPositionConstraints(constraints, renderer.constrainingRectForStickyPosition());

    auto* graphicsLayer = layer.backing()->graphicsLayer();
    constraints.setLayerPositionAtLastLayout(graphicsLayer->position());
    constraints.setStickyOffsetAtLastLayout(renderer.stickyPositionOffset());
    constraints.setAlignmentOffset(graphicsLayer->pixelAlignmentOffset());

    return constraints;
}

static ScrollingNodeID enclosingScrollingNodeID(RenderLayer& layer, IncludeSelfOrNot includeSelf)
{
    auto* currLayer = includeSelf == IncludeSelf ? &layer : layer.parent();
    while (currLayer) {
        if (auto* backing = currLayer->backing()) {
            if (ScrollingNodeID nodeID = backing->scrollingNodeIDForChildren())
                return nodeID;
        }
        currLayer = currLayer->parent();
    }

    return 0;
}

static ScrollingNodeID scrollCoordinatedAncestorInParentOfFrame(Frame& frame)
{
    if (!frame.document() || !frame.view())
        return 0;

    // Find the frame's enclosing layer in our render tree.
    auto* ownerElement = frame.document()->ownerElement();
    auto* frameRenderer = ownerElement ? ownerElement->renderer() : nullptr;
    if (!frameRenderer)
        return 0;

    auto* layerInParentDocument = frameRenderer->enclosingLayer();
    if (!layerInParentDocument)
        return 0;

    return enclosingScrollingNodeID(*layerInParentDocument, IncludeSelf);
}

void RenderLayerCompositor::reattachSubframeScrollLayers()
{
    if (!m_subframeScrollLayersNeedReattach)
        return;
    
    m_subframeScrollLayersNeedReattach = false;

    auto* scrollingCoordinator = this->scrollingCoordinator();

    for (Frame* child = m_renderView.frameView().frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
        if (!child->document() || !child->view())
            continue;

        // Ignore frames that are not scroll-coordinated.
        auto* childFrameView = child->view();
        ScrollingNodeID frameScrollingNodeID = childFrameView->scrollLayerID();
        if (!frameScrollingNodeID)
            continue;

        ScrollingNodeID parentNodeID = scrollCoordinatedAncestorInParentOfFrame(*child);
        if (!parentNodeID)
            continue;

        scrollingCoordinator->attachToStateTree(child->isMainFrame() ? MainFrameScrollingNode : SubframeScrollingNode, frameScrollingNodeID, parentNodeID);
    }
}

static inline LayerScrollCoordinationRole scrollCoordinationRoleForNodeType(ScrollingNodeType nodeType)
{
    switch (nodeType) {
    case MainFrameScrollingNode:
    case SubframeScrollingNode:
    case OverflowScrollingNode:
        return Scrolling;
    case FixedNode:
    case StickyNode:
        return ViewportConstrained;
    }
    ASSERT_NOT_REACHED();
    return Scrolling;
}

ScrollingNodeID RenderLayerCompositor::attachScrollingNode(RenderLayer& layer, ScrollingNodeType nodeType, ScrollingNodeID parentNodeID)
{
    auto* scrollingCoordinator = this->scrollingCoordinator();
    auto* backing = layer.backing();
    // Crash logs suggest that backing can be null here, but we don't know how: rdar://problem/18545452.
    ASSERT(backing);
    if (!backing)
        return 0;

    LayerScrollCoordinationRole role = scrollCoordinationRoleForNodeType(nodeType);
    ScrollingNodeID nodeID = backing->scrollingNodeIDForRole(role);
    if (!nodeID)
        nodeID = scrollingCoordinator->uniqueScrollLayerID();

    nodeID = scrollingCoordinator->attachToStateTree(nodeType, nodeID, parentNodeID);
    if (!nodeID)
        return 0;

    backing->setScrollingNodeIDForRole(nodeID, role);
    m_scrollingNodeToLayerMap.add(nodeID, &layer);
    
    return nodeID;
}

void RenderLayerCompositor::detachScrollCoordinatedLayer(RenderLayer& layer, LayerScrollCoordinationRoles roles)
{
    auto* backing = layer.backing();
    if (!backing)
        return;

    if (roles & Scrolling) {
        if (ScrollingNodeID nodeID = backing->scrollingNodeIDForRole(Scrolling))
            m_scrollingNodeToLayerMap.remove(nodeID);
    }

    if (roles & ViewportConstrained) {
        if (ScrollingNodeID nodeID = backing->scrollingNodeIDForRole(ViewportConstrained))
            m_scrollingNodeToLayerMap.remove(nodeID);
    }

    backing->detachFromScrollingCoordinator(roles);
}

void RenderLayerCompositor::updateScrollCoordinationForThisFrame(ScrollingNodeID parentNodeID)
{
    auto* scrollingCoordinator = this->scrollingCoordinator();
    ASSERT(scrollingCoordinator->coordinatesScrollingForFrameView(m_renderView.frameView()));

    ScrollingNodeID nodeID = attachScrollingNode(*m_renderView.layer(), m_renderView.frame().isMainFrame() ? MainFrameScrollingNode : SubframeScrollingNode, parentNodeID);
    scrollingCoordinator->updateFrameScrollingNode(nodeID, m_scrollLayer.get(), m_rootContentLayer.get(), fixedRootBackgroundLayer(), clipLayer());
}

void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, LayerScrollCoordinationRoles reasons, OptionSet<ScrollingNodeChangeFlags> changes)
{
    bool isRenderViewLayer = layer.isRenderViewLayer();

    ASSERT(m_scrollCoordinatedLayers.contains(&layer));
    ASSERT(layer.isComposited());

    auto* scrollingCoordinator = this->scrollingCoordinator();
    if (!scrollingCoordinator || !scrollingCoordinator->coordinatesScrollingForFrameView(m_renderView.frameView()))
        return;

    if (!m_renderView.frame().isMainFrame()) {
        ScrollingNodeID parentDocumentHostingNodeID = scrollCoordinatedAncestorInParentOfFrame(m_renderView.frame());
        if (!parentDocumentHostingNodeID)
            return;

        updateScrollCoordinationForThisFrame(parentDocumentHostingNodeID);
        if (!(reasons & ViewportConstrained) && isRenderViewLayer)
            return;
    }

    ScrollingNodeID parentNodeID = enclosingScrollingNodeID(layer, ExcludeSelf);
    if (!parentNodeID && !isRenderViewLayer)
        return;

    auto* backing = layer.backing();

    // Always call this even if the backing is already attached because the parent may have changed.
    // If a node plays both roles, fixed/sticky is always the ancestor node of scrolling.
    if (reasons & ViewportConstrained) {
        ScrollingNodeType nodeType = MainFrameScrollingNode;
        if (layer.renderer().isFixedPositioned())
            nodeType = FixedNode;
        else if (layer.renderer().style().position() == StickyPosition)
            nodeType = StickyNode;
        else
            ASSERT_NOT_REACHED();

        ScrollingNodeID nodeID = attachScrollingNode(layer, nodeType, parentNodeID);
        if (!nodeID)
            return;
            
        LOG_WITH_STREAM(Compositing, stream << "Registering ViewportConstrained " << nodeType << " node " << nodeID << " (layer " << backing->graphicsLayer()->primaryLayerID() << ") as child of " << parentNodeID);

        if (changes.contains(ScrollingNodeChangeFlags::Layer))
            scrollingCoordinator->updateNodeLayer(nodeID, backing->graphicsLayer());

        if (changes.contains(ScrollingNodeChangeFlags::LayerGeometry)) {
            switch (nodeType) {
            case FixedNode:
                scrollingCoordinator->updateNodeViewportConstraints(nodeID, computeFixedViewportConstraints(layer));
                break;
            case StickyNode:
                scrollingCoordinator->updateNodeViewportConstraints(nodeID, computeStickyViewportConstraints(layer));
                break;
            case MainFrameScrollingNode:
            case SubframeScrollingNode:
            case OverflowScrollingNode:
                break;
            }
        }
        
        parentNodeID = nodeID;
    } else
        detachScrollCoordinatedLayer(layer, ViewportConstrained);
        
    if (reasons & Scrolling) {
        if (isRenderViewLayer)
            updateScrollCoordinationForThisFrame(parentNodeID);
        else {
            ScrollingNodeType nodeType = OverflowScrollingNode;
            ScrollingNodeID nodeID = attachScrollingNode(layer, nodeType, parentNodeID);
            if (!nodeID)
                return;

            ScrollingCoordinator::ScrollingGeometry scrollingGeometry;
            scrollingGeometry.scrollOrigin = layer.scrollOrigin();
            scrollingGeometry.scrollPosition = layer.scrollPosition();
            scrollingGeometry.scrollableAreaSize = layer.visibleSize();
            scrollingGeometry.contentSize = layer.contentsSize();
            scrollingGeometry.reachableContentSize = layer.scrollableContentsSize();
#if ENABLE(CSS_SCROLL_SNAP)
            if (const Vector<LayoutUnit>* offsets = layer.horizontalSnapOffsets())
                scrollingGeometry.horizontalSnapOffsets = *offsets;
            if (const Vector<LayoutUnit>* offsets = layer.verticalSnapOffsets())
                scrollingGeometry.verticalSnapOffsets = *offsets;
            if (const Vector<ScrollOffsetRange<LayoutUnit>>* ranges = layer.horizontalSnapOffsetRanges())
                scrollingGeometry.horizontalSnapOffsetRanges = *ranges;
            if (const Vector<ScrollOffsetRange<LayoutUnit>>* ranges = layer.verticalSnapOffsetRanges())
                scrollingGeometry.verticalSnapOffsetRanges = *ranges;
            scrollingGeometry.currentHorizontalSnapPointIndex = layer.currentHorizontalSnapPointIndex();
            scrollingGeometry.currentVerticalSnapPointIndex = layer.currentVerticalSnapPointIndex();
#endif

            LOG(Compositing, "Registering Scrolling scrolling node %" PRIu64 " (layer %" PRIu64 ") as child of %" PRIu64, nodeID, backing->graphicsLayer()->primaryLayerID(), parentNodeID);

            scrollingCoordinator->updateOverflowScrollingNode(nodeID, backing->scrollingLayer(), backing->scrollingContentsLayer(), &scrollingGeometry);
        }
    } else
        detachScrollCoordinatedLayer(layer, Scrolling);
}

ScrollableArea* RenderLayerCompositor::scrollableAreaForScrollLayerID(ScrollingNodeID nodeID) const
{
    if (!nodeID)
        return nullptr;

    return m_scrollingNodeToLayerMap.get(nodeID);
}

#if PLATFORM(IOS)
typedef HashMap<PlatformLayer*, std::unique_ptr<ViewportConstraints>> LayerMap;
typedef HashMap<PlatformLayer*, PlatformLayer*> StickyContainerMap;

void RenderLayerCompositor::registerAllViewportConstrainedLayers()
{
    // Only the main frame should register fixed/sticky layers.
    if (!isMainFrameCompositor())
        return;

    if (scrollingCoordinator())
        return;

    LayerMap layerMap;
    StickyContainerMap stickyContainerMap;

    for (auto* layer : m_scrollCoordinatedLayers) {
        ASSERT(layer->isComposited());

        std::unique_ptr<ViewportConstraints> constraints;
        if (layer->renderer().isStickilyPositioned()) {
            constraints = std::make_unique<StickyPositionViewportConstraints>(computeStickyViewportConstraints(*layer));
            const RenderLayer* enclosingTouchScrollableLayer = nullptr;
            if (isAsyncScrollableStickyLayer(*layer, &enclosingTouchScrollableLayer) && enclosingTouchScrollableLayer) {
                ASSERT(enclosingTouchScrollableLayer->isComposited());
                stickyContainerMap.add(layer->backing()->graphicsLayer()->platformLayer(), enclosingTouchScrollableLayer->backing()->scrollingLayer()->platformLayer());
            }
        } else if (layer->renderer().isFixedPositioned())
            constraints = std::make_unique<FixedPositionViewportConstraints>(computeFixedViewportConstraints(*layer));
        else
            continue;

        layerMap.add(layer->backing()->graphicsLayer()->platformLayer(), WTFMove(constraints));
    }
    
    page().chrome().client().updateViewportConstrainedLayers(layerMap, stickyContainerMap);
}

void RenderLayerCompositor::unregisterAllViewportConstrainedLayers()
{
    // Only the main frame should register fixed/sticky layers.
    if (!isMainFrameCompositor())
        return;

    if (scrollingCoordinator())
        return;

    LayerMap layerMap;
    StickyContainerMap stickyContainerMap;
    page().chrome().client().updateViewportConstrainedLayers(layerMap, stickyContainerMap);
}

void RenderLayerCompositor::registerAllScrollingLayers()
{
    for (auto* layer : m_scrollingLayers)
        updateScrollingLayerWithClient(*layer, page().chrome().client());
}

void RenderLayerCompositor::unregisterAllScrollingLayers()
{
    for (auto* layer : m_scrollingLayers) {
        auto* backing = layer->backing();
        ASSERT(backing);
        page().chrome().client().removeScrollingLayer(layer->renderer().element(), backing->scrollingLayer()->platformLayer(), backing->scrollingContentsLayer()->platformLayer());
    }
}
#endif

void RenderLayerCompositor::willRemoveScrollingLayerWithBacking(RenderLayer& layer, RenderLayerBacking& backing)
{
    if (auto* scrollingCoordinator = this->scrollingCoordinator()) {
        backing.detachFromScrollingCoordinator(Scrolling);

        // For Coordinated Graphics.
        scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer);
        return;
    }

#if PLATFORM(IOS)
    m_scrollingLayersNeedingUpdate.remove(&layer);
    m_scrollingLayers.remove(&layer);

    if (m_renderView.document().pageCacheState() != Document::NotInPageCache)
        return;

    auto* scrollingLayer = backing.scrollingLayer()->platformLayer();
    auto* contentsLayer = backing.scrollingContentsLayer()->platformLayer();
    page().chrome().client().removeScrollingLayer(layer.renderer().element(), scrollingLayer, contentsLayer);
#endif
}

void RenderLayerCompositor::didAddScrollingLayer(RenderLayer& layer)
{
    updateScrollCoordinatedStatus(layer, { ScrollingNodeChangeFlags::Layer, ScrollingNodeChangeFlags::LayerGeometry });

    if (auto* scrollingCoordinator = this->scrollingCoordinator()) {
        // For Coordinated Graphics.
        scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer);
        return;
    }

#if PLATFORM(IOS)
    ASSERT(m_renderView.document().pageCacheState() == Document::NotInPageCache);
    m_scrollingLayers.add(&layer);
#endif
}

void RenderLayerCompositor::windowScreenDidChange(PlatformDisplayID displayID)
{
    if (m_layerUpdater)
        m_layerUpdater->screenDidChange(displayID);
}

ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
{
    return page().scrollingCoordinator();
}

GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
{
    return page().chrome().client().graphicsLayerFactory();
}

void RenderLayerCompositor::setLayerFlushThrottlingEnabled(bool enabled)
{
    m_layerFlushThrottlingEnabled = enabled;
    if (m_layerFlushThrottlingEnabled)
        return;
    m_layerFlushTimer.stop();
    if (!m_hasPendingLayerFlush)
        return;
    scheduleLayerFlushNow();
}

void RenderLayerCompositor::disableLayerFlushThrottlingTemporarilyForInteraction()
{
    if (m_layerFlushThrottlingTemporarilyDisabledForInteraction)
        return;
    m_layerFlushThrottlingTemporarilyDisabledForInteraction = true;
}

bool RenderLayerCompositor::isThrottlingLayerFlushes() const
{
    if (!m_layerFlushThrottlingEnabled)
        return false;
    if (!m_layerFlushTimer.isActive())
        return false;
    if (m_layerFlushThrottlingTemporarilyDisabledForInteraction)
        return false;
    return true;
}

void RenderLayerCompositor::startLayerFlushTimerIfNeeded()
{
    m_layerFlushThrottlingTemporarilyDisabledForInteraction = false;
    m_layerFlushTimer.stop();
    if (!m_layerFlushThrottlingEnabled)
        return;
    m_layerFlushTimer.startOneShot(throttledLayerFlushDelay);
}

void RenderLayerCompositor::startInitialLayerFlushTimerIfNeeded()
{
    if (!m_layerFlushThrottlingEnabled)
        return;
    if (m_layerFlushTimer.isActive())
        return;
    m_layerFlushTimer.startOneShot(throttledLayerFlushInitialDelay);
}

void RenderLayerCompositor::layerFlushTimerFired()
{
    if (!m_hasPendingLayerFlush)
        return;
    scheduleLayerFlushNow();
}

#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
RefPtr<DisplayRefreshMonitor> RenderLayerCompositor::createDisplayRefreshMonitor(PlatformDisplayID displayID) const
{
    if (auto monitor = page().chrome().client().createDisplayRefreshMonitor(displayID))
        return monitor;

    return DisplayRefreshMonitor::createDefaultDisplayRefreshMonitor(displayID);
}
#endif

#if ENABLE(CSS_SCROLL_SNAP)
void RenderLayerCompositor::updateScrollSnapPropertiesWithFrameView(const FrameView& frameView)
{
    if (auto* coordinator = scrollingCoordinator())
        coordinator->updateScrollSnapPropertiesWithFrameView(frameView);
}
#endif

Page& RenderLayerCompositor::page() const
{
    return m_renderView.page();
}

TextStream& operator<<(TextStream& ts, CompositingUpdateType updateType)
{
    switch (updateType) {
    case CompositingUpdateType::AfterStyleChange: ts << "after style change"; break;
    case CompositingUpdateType::AfterLayout: ts << "after layout"; break;
    case CompositingUpdateType::OnHitTest: ts << "on hit test"; break;
    case CompositingUpdateType::OnScroll: ts << "on scroll"; break;
    case CompositingUpdateType::OnCompositedScroll: ts << "on composited scroll"; break;
    }
    return ts;
}

} // namespace WebCore
