/*
 * Copyright (C) 2009-2021 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. 
 */

#pragma once

#include "Color.h"
#include "EventRegion.h"
#include "FilterOperations.h"
#include "FloatPoint.h"
#include "FloatPoint3D.h"
#include "FloatRoundedRect.h"
#include "FloatSize.h"
#include "GraphicsLayerClient.h"
#include "Path.h"
#include "PlatformLayer.h"
#include "Region.h"
#include "ScrollableArea.h"
#include "ScrollTypes.h"
#include "TimingFunction.h"
#include "TransformOperations.h"
#include "WindRule.h"
#include <wtf/EnumTraits.h>
#include <wtf/Function.h>
#include <wtf/TypeCasts.h>

#if ENABLE(CSS_COMPOSITING)
#include "GraphicsTypes.h"
#endif

namespace WTF {
class TextStream;
}

namespace WebCore {

class Animation;
class GraphicsContext;
class GraphicsLayerFactory;
class GraphicsLayerContentsDisplayDelegate;
class Image;
class Model;
class TiledBacking;
class TimingFunction;
class TransformationMatrix;

namespace DisplayList {
typedef unsigned AsTextFlags;
}

// Base class for animation values (also used for transitions). Here to
// represent values for properties being animated via the GraphicsLayer,
// without pulling in style-related data from outside of the platform directory.
// FIXME: Should be moved to its own header file.
class AnimationValue {
    WTF_MAKE_FAST_ALLOCATED;
public:
    virtual ~AnimationValue() = default;

    double keyTime() const { return m_keyTime; }
    const TimingFunction* timingFunction() const { return m_timingFunction.get(); }
    virtual std::unique_ptr<AnimationValue> clone() const = 0;

protected:
    AnimationValue(double keyTime, TimingFunction* timingFunction = nullptr)
        : m_keyTime(keyTime)
        , m_timingFunction(timingFunction)
    {
    }

    AnimationValue(const AnimationValue& other)
        : m_keyTime(other.m_keyTime)
        , m_timingFunction(other.m_timingFunction ? RefPtr<TimingFunction> { other.m_timingFunction->clone() } : nullptr)
    {
    }

    AnimationValue(AnimationValue&&) = default;

private:
    void operator=(const AnimationValue&) = delete;

    double m_keyTime;
    RefPtr<TimingFunction> m_timingFunction;
};

// Used to store one float value of an animation.
// FIXME: Should be moved to its own header file.
class FloatAnimationValue : public AnimationValue {
public:
    FloatAnimationValue(double keyTime, float value, TimingFunction* timingFunction = nullptr)
        : AnimationValue(keyTime, timingFunction)
        , m_value(value)
    {
    }

    std::unique_ptr<AnimationValue> clone() const override
    {
        return makeUnique<FloatAnimationValue>(*this);
    }

    float value() const { return m_value; }

private:
    float m_value;
};

// Used to store one transform value in a keyframe list.
// FIXME: Should be moved to its own header file.
class TransformAnimationValue : public AnimationValue {
public:
    TransformAnimationValue(double keyTime, const TransformOperations& value, TimingFunction* timingFunction = nullptr)
        : AnimationValue(keyTime, timingFunction)
        , m_value(value)
    {
    }

    TransformAnimationValue(double keyTime, TransformOperation* value, TimingFunction* timingFunction = nullptr)
        : AnimationValue(keyTime, timingFunction)
    {
        if (value)
            m_value.operations().append(value);
    }

    std::unique_ptr<AnimationValue> clone() const override
    {
        return makeUnique<TransformAnimationValue>(*this);
    }

    TransformAnimationValue(const TransformAnimationValue& other)
        : AnimationValue(other)
    {
        m_value.operations().reserveInitialCapacity(other.m_value.operations().size());
        for (auto& operation : other.m_value.operations())
            m_value.operations().uncheckedAppend(operation->clone());
    }

    TransformAnimationValue(TransformAnimationValue&&) = default;

    const TransformOperations& value() const { return m_value; }

private:
    TransformOperations m_value;
};

// Used to store one filter value in a keyframe list.
// FIXME: Should be moved to its own header file.
class FilterAnimationValue : public AnimationValue {
public:
    FilterAnimationValue(double keyTime, const FilterOperations& value, TimingFunction* timingFunction = nullptr)
        : AnimationValue(keyTime, timingFunction)
        , m_value(value)
    {
    }

    std::unique_ptr<AnimationValue> clone() const override
    {
        return makeUnique<FilterAnimationValue>(*this);
    }

    FilterAnimationValue(const FilterAnimationValue& other)
        : AnimationValue(other)
    {
        m_value.operations().reserveInitialCapacity(other.m_value.operations().size());
        for (auto& operation : other.m_value.operations())
            m_value.operations().uncheckedAppend(operation->clone());
    }

    FilterAnimationValue(FilterAnimationValue&&) = default;

    const FilterOperations& value() const { return m_value; }

private:
    FilterOperations m_value;
};

// Used to store a series of values in a keyframe list.
// Values will all be of the same type, which can be inferred from the property.
// FIXME: Should be moved to its own header file.
class KeyframeValueList {
public:
    explicit KeyframeValueList(AnimatedPropertyID property)
        : m_property(property)
    {
    }

    KeyframeValueList(const KeyframeValueList& other)
        : m_property(other.property())
    {
        m_values.reserveInitialCapacity(other.m_values.size());
        for (auto& value : other.m_values)
            m_values.uncheckedAppend(value->clone());
    }

    KeyframeValueList(KeyframeValueList&&) = default;

    KeyframeValueList& operator=(const KeyframeValueList& other)
    {
        KeyframeValueList copy(other);
        swap(copy);
        return *this;
    }

    KeyframeValueList& operator=(KeyframeValueList&&) = default;

    void swap(KeyframeValueList& other)
    {
        std::swap(m_property, other.m_property);
        m_values.swap(other.m_values);
    }

    AnimatedPropertyID property() const { return m_property; }

    size_t size() const { return m_values.size(); }
    const AnimationValue& at(size_t i) const { return *m_values.at(i); }

    // Insert, sorted by keyTime.
    WEBCORE_EXPORT void insert(std::unique_ptr<const AnimationValue>);

protected:
    Vector<std::unique_ptr<const AnimationValue>> m_values;
    AnimatedPropertyID m_property;
};

// GraphicsLayer is an abstraction for a rendering surface with backing store,
// which may have associated transformation and animations.

class GraphicsLayer : public RefCounted<GraphicsLayer> {
    WTF_MAKE_FAST_ALLOCATED;
public:
    enum class Type : uint8_t {
        Normal,
        PageTiledBacking,
        ScrollContainer,
        ScrolledContents,
        Shape
    };

    WEBCORE_EXPORT static Ref<GraphicsLayer> create(GraphicsLayerFactory*, GraphicsLayerClient&, Type = Type::Normal);
    
    WEBCORE_EXPORT virtual ~GraphicsLayer();
    
    // Unparent, clear the client, and clear the RefPtr.
    WEBCORE_EXPORT static void unparentAndClear(RefPtr<GraphicsLayer>&);
    // Clear the client, and clear the RefPtr, but leave parented.
    WEBCORE_EXPORT static void clear(RefPtr<GraphicsLayer>&);

    WEBCORE_EXPORT void clearClient();
    WEBCORE_EXPORT void setClient(GraphicsLayerClient&);

    Type type() const { return m_type; }

    virtual void initialize(Type) { }

    using PlatformLayerID = uint64_t;
    virtual PlatformLayerID primaryLayerID() const { return 0; }

    GraphicsLayerClient& client() const { return *m_client; }

    // Layer name. Only used to identify layers in debug output
    const String& name() const { return m_name; }
    virtual void setName(const String& name) { m_name = name; }
    virtual String debugName() const;

    GraphicsLayer* parent() const { return m_parent; };
    void setParent(GraphicsLayer*); // Internal use only.
    
    // Returns true if the layer has the given layer as an ancestor (excluding self).
    bool hasAncestor(GraphicsLayer*) const;
    
    const Vector<Ref<GraphicsLayer>>& children() const { return m_children; }
    Vector<Ref<GraphicsLayer>>& children() { return m_children; }

    // Returns true if the child list changed.
    WEBCORE_EXPORT virtual bool setChildren(Vector<Ref<GraphicsLayer>>&&);

    // Add child layers. If the child is already parented, it will be removed from its old parent.
    WEBCORE_EXPORT virtual void addChild(Ref<GraphicsLayer>&&);
    WEBCORE_EXPORT virtual void addChildAtIndex(Ref<GraphicsLayer>&&, int index);
    WEBCORE_EXPORT virtual void addChildAbove(Ref<GraphicsLayer>&&, GraphicsLayer* sibling);
    WEBCORE_EXPORT virtual void addChildBelow(Ref<GraphicsLayer>&&, GraphicsLayer* sibling);
    WEBCORE_EXPORT virtual bool replaceChild(GraphicsLayer* oldChild, Ref<GraphicsLayer>&& newChild);

    WEBCORE_EXPORT void removeAllChildren();
    WEBCORE_EXPORT virtual void removeFromParent();

    // The parent() of a maskLayer is set to the layer being masked.
    GraphicsLayer* maskLayer() const { return m_maskLayer.get(); }
    virtual void setMaskLayer(RefPtr<GraphicsLayer>&&);

    void setIsMaskLayer(bool isMask) { m_isMaskLayer = isMask; }
    bool isMaskLayer() const { return m_isMaskLayer; }
    
    // The given layer will replicate this layer and its children; the replica renders behind this layer.
    WEBCORE_EXPORT virtual void setReplicatedByLayer(RefPtr<GraphicsLayer>&&);
    // Whether this layer is being replicated by another layer.
    bool isReplicated() const { return m_replicaLayer; }
    // The layer that replicates this layer (if any).
    GraphicsLayer* replicaLayer() const { return m_replicaLayer.get(); }

    const FloatPoint& replicatedLayerPosition() const { return m_replicatedLayerPosition; }
    void setReplicatedLayerPosition(const FloatPoint& p) { m_replicatedLayerPosition = p; }

    enum ShouldSetNeedsDisplay {
        DontSetNeedsDisplay,
        SetNeedsDisplay
    };

    // Offset is origin of the renderer minus origin of the graphics layer.
    FloatSize offsetFromRenderer() const { return m_offsetFromRenderer; }
    void setOffsetFromRenderer(const FloatSize&, ShouldSetNeedsDisplay = SetNeedsDisplay);

    // Scroll offset of the content layer inside its scrolling parent layer.
    ScrollOffset scrollOffset() const { return m_scrollOffset; }
    void setScrollOffset(const ScrollOffset&, ShouldSetNeedsDisplay = SetNeedsDisplay);

#if ENABLE(SCROLLING_THREAD)
    ScrollingNodeID scrollingNodeID() const { return m_scrollingNodeID; }
    virtual void setScrollingNodeID(ScrollingNodeID nodeID) { m_scrollingNodeID = nodeID; }
#endif

    // The position of the layer (the location of its top-left corner in its parent)
    const FloatPoint& position() const { return m_position; }
    virtual void setPosition(const FloatPoint& p) { m_approximatePosition = std::nullopt; m_position = p; }

    // approximatePosition, if set, overrides position() and is used during coverage rect computation.
    FloatPoint approximatePosition() const { return m_approximatePosition ? m_approximatePosition.value() : m_position; }
    virtual void setApproximatePosition(const FloatPoint& p) { m_approximatePosition = p; }

    // For platforms that move underlying platform layers on a different thread for scrolling; just update the GraphicsLayer state.
    virtual void syncPosition(const FloatPoint& p) { m_position = p; }

    // Anchor point: (0, 0) is top left, (1, 1) is bottom right. The anchor point
    // affects the origin of the transforms.
    const FloatPoint3D& anchorPoint() const { return m_anchorPoint; }
    virtual void setAnchorPoint(const FloatPoint3D& p) { m_anchorPoint = p; }

    // The size of the layer.
    const FloatSize& size() const { return m_size; }
    WEBCORE_EXPORT virtual void setSize(const FloatSize&);

    // The boundOrigin affects the offset at which content is rendered, and sublayers are positioned.
    const FloatPoint& boundsOrigin() const { return m_boundsOrigin; }
    virtual void setBoundsOrigin(const FloatPoint& origin) { m_boundsOrigin = origin; }

    // For platforms that move underlying platform layers on a different thread for scrolling; just update the GraphicsLayer state.
    virtual void syncBoundsOrigin(const FloatPoint& origin) { m_boundsOrigin = origin; }

    const TransformationMatrix& transform() const;
    virtual void setTransform(const TransformationMatrix&);
    bool hasNonIdentityTransform() const { return m_transform && !m_transform->isIdentity(); }

    const TransformationMatrix& childrenTransform() const;
    virtual void setChildrenTransform(const TransformationMatrix&);
    bool hasNonIdentityChildrenTransform() const { return m_childrenTransform && !m_childrenTransform->isIdentity(); }

    bool preserves3D() const { return m_preserves3D; }
    virtual void setPreserves3D(bool b) { m_preserves3D = b; }
    
    bool masksToBounds() const { return m_masksToBounds; }
    virtual void setMasksToBounds(bool b) { m_masksToBounds = b; }
    
    bool drawsContent() const { return m_drawsContent; }
    virtual void setDrawsContent(bool b) { m_drawsContent = b; }

    bool contentsAreVisible() const { return m_contentsVisible; }
    virtual void setContentsVisible(bool b) { m_contentsVisible = b; }

    bool userInteractionEnabled() const { return m_userInteractionEnabled; }
    virtual void setUserInteractionEnabled(bool b) { m_userInteractionEnabled = b; }
    
    bool acceleratesDrawing() const { return m_acceleratesDrawing; }
    virtual void setAcceleratesDrawing(bool b) { m_acceleratesDrawing = b; }

    bool usesDisplayListDrawing() const { return m_usesDisplayListDrawing; }
    virtual void setUsesDisplayListDrawing(bool b) { m_usesDisplayListDrawing = b; }

#if HAVE(CORE_ANIMATION_SEPARATED_LAYERS)
    bool isIsSeparated() const { return m_isSeparated; }
    virtual void setIsSeparated(bool b) { m_isSeparated = b; }

#if HAVE(CORE_ANIMATION_SEPARATED_PORTALS)
    bool isSeparatedPortal() const { return m_isSeparatedPortal; }
    virtual void setIsSeparatedPortal(bool b) { m_isSeparatedPortal = b; }
#endif
#endif

    bool needsBackdrop() const { return !m_backdropFilters.isEmpty(); }

    // The color used to paint the layer background. Pass an invalid color to remove it.
    // Note that this covers the entire layer. Use setContentsToSolidColor() if the color should
    // only cover the contentsRect.
    const Color& backgroundColor() const { return m_backgroundColor; }
    WEBCORE_EXPORT virtual void setBackgroundColor(const Color&);

    // opaque means that we know the layer contents have no alpha
    bool contentsOpaque() const { return m_contentsOpaque; }
    virtual void setContentsOpaque(bool b) { m_contentsOpaque = b; }

    bool supportsSubpixelAntialiasedText() const { return m_supportsSubpixelAntialiasedText; }
    virtual void setSupportsSubpixelAntialiasedText(bool b) { m_supportsSubpixelAntialiasedText = b; }

    bool backfaceVisibility() const { return m_backfaceVisibility; }
    virtual void setBackfaceVisibility(bool b) { m_backfaceVisibility = b; }

    float opacity() const { return m_opacity; }
    virtual void setOpacity(float opacity) { m_opacity = opacity; }

    const FilterOperations& filters() const { return m_filters; }
    // Returns true if filter can be rendered by the compositor.
    virtual bool setFilters(const FilterOperations& filters) { m_filters = filters; return true; }

    const FilterOperations& backdropFilters() const { return m_backdropFilters; }
    virtual bool setBackdropFilters(const FilterOperations& filters) { m_backdropFilters = filters; return true; }

    virtual void setBackdropFiltersRect(const FloatRoundedRect& backdropFiltersRect) { m_backdropFiltersRect = backdropFiltersRect; }
    const FloatRoundedRect& backdropFiltersRect() const { return m_backdropFiltersRect; }

#if ENABLE(CSS_COMPOSITING)
    BlendMode blendMode() const { return m_blendMode; }
    virtual void setBlendMode(BlendMode blendMode) { m_blendMode = blendMode; }
#endif

    // Some GraphicsLayers paint only the foreground or the background content
    OptionSet<GraphicsLayerPaintingPhase> paintingPhase() const { return m_paintingPhase; }
    void setPaintingPhase(OptionSet<GraphicsLayerPaintingPhase>);

    enum ShouldClipToLayer {
        DoNotClipToLayer,
        ClipToLayer
    };

    virtual void setNeedsDisplay() = 0;
    // mark the given rect (in layer coords) as needing dispay. Never goes deep.
    virtual void setNeedsDisplayInRect(const FloatRect&, ShouldClipToLayer = ClipToLayer) = 0;

    virtual void setContentsNeedsDisplay() { };

    // The tile phase is relative to the GraphicsLayer bounds.
    virtual void setContentsTilePhase(const FloatSize& p) { m_contentsTilePhase = p; }
    FloatSize contentsTilePhase() const { return m_contentsTilePhase; }

    virtual void setContentsTileSize(const FloatSize& s) { m_contentsTileSize = s; }
    FloatSize contentsTileSize() const { return m_contentsTileSize; }
    bool hasContentsTiling() const { return !m_contentsTileSize.isEmpty(); }

    // Set that the position/size of the contents (image or video).
    FloatRect contentsRect() const { return m_contentsRect; }
    virtual void setContentsRect(const FloatRect& r) { m_contentsRect = r; }

    // Set a rounded rect that will be used to clip the layer contents.
    FloatRoundedRect contentsClippingRect() const { return m_contentsClippingRect; }
    virtual void setContentsClippingRect(const FloatRoundedRect& roundedRect) { m_contentsClippingRect = roundedRect; }
    
    // If true, contentsClippingRect is used to clip child GraphicsLayers.
    bool contentsRectClipsDescendants() const { return m_contentsRectClipsDescendants; }
    virtual void setContentsRectClipsDescendants(bool b) { m_contentsRectClipsDescendants = b; }

    // Set a rounded rect that is used to clip this layer and its descendants (implies setting masksToBounds).
    // Consult supportsRoundedClip() to know whether non-zero radii are supported.
    FloatRoundedRect maskToBoundsRect() const { return m_masksToBoundsRect; };
    virtual void setMasksToBoundsRect(const FloatRoundedRect&);

    Path shapeLayerPath() const;
    virtual void setShapeLayerPath(const Path&);

    WindRule shapeLayerWindRule() const;
    virtual void setShapeLayerWindRule(WindRule);

    const EventRegion& eventRegion() const { return m_eventRegion; }
    virtual void setEventRegion(EventRegion&&);

    // Transitions are identified by a special animation name that cannot clash with a keyframe identifier.
    static String animationNameForTransition(AnimatedPropertyID);

    // Return true if the animation is handled by the compositing system.
    virtual bool addAnimation(const KeyframeValueList&, const FloatSize& /*boxSize*/, const Animation*, const String& /*animationName*/, double /*timeOffset*/)  { return false; }
    virtual void pauseAnimation(const String& /*animationName*/, double /*timeOffset*/) { }
    virtual void removeAnimation(const String& /*animationName*/) { }
    virtual void transformRelatedPropertyDidChange() { }
    WEBCORE_EXPORT virtual void suspendAnimations(MonotonicTime);
    WEBCORE_EXPORT virtual void resumeAnimations();

    virtual Vector<std::pair<String, double>> acceleratedAnimationsForTesting() const { return { }; }

    // Layer contents
    virtual void setContentsToImage(Image*) { }
    virtual bool shouldDirectlyCompositeImage(Image*) const { return true; }
#if PLATFORM(IOS_FAMILY)
    virtual PlatformLayer* contentsLayerForMedia() const { return 0; }
#endif

    enum class ContentsLayerPurpose : uint8_t {
        None = 0,
        Image,
        Media,
        Canvas,
        BackgroundColor,
        Plugin,
        Model
    };

    // Pass an invalid color to remove the contents layer.
    virtual void setContentsToSolidColor(const Color&) { }
    virtual void setContentsToPlatformLayer(PlatformLayer*, ContentsLayerPurpose) { }
    virtual void setContentsDisplayDelegate(RefPtr<GraphicsLayerContentsDisplayDelegate>&&, ContentsLayerPurpose);
#if ENABLE(MODEL_ELEMENT)
    virtual void setContentsToModel(RefPtr<Model>&&) { }
    virtual PlatformLayerID contentsLayerIDForModel() const { return 0; }
#endif
    virtual bool usesContentsLayer() const { return false; }

    // Callback from the underlying graphics system to draw layer contents.
    void paintGraphicsLayerContents(GraphicsContext&, const FloatRect& clip, GraphicsLayerPaintBehavior = GraphicsLayerPaintNormal);

    // For hosting this GraphicsLayer in a native layer hierarchy.
    virtual PlatformLayer* platformLayer() const { return 0; }

    enum class CompositingCoordinatesOrientation : uint8_t { TopDown, BottomUp };

    // Flippedness of the contents of this layer. Does not affect sublayer geometry.
    virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation) { m_contentsOrientation = orientation; }
    CompositingCoordinatesOrientation contentsOrientation() const { return m_contentsOrientation; }

    enum class ScalingFilter { Linear, Nearest, Trilinear };
    virtual void setContentsMinificationFilter(ScalingFilter filter) { m_contentsMinificationFilter = filter; }
    ScalingFilter contentsMinificationFilter() const { return m_contentsMinificationFilter; }
    virtual void setContentsMagnificationFilter(ScalingFilter filter) { m_contentsMagnificationFilter = filter; }
    ScalingFilter contentsMagnificationFilter() const { return m_contentsMagnificationFilter; }

    void dumpLayer(WTF::TextStream&, OptionSet<LayerTreeAsTextOptions> = { }) const;

    virtual void setShowDebugBorder(bool show) { m_showDebugBorder = show; }
    bool isShowingDebugBorder() const { return m_showDebugBorder; }

    virtual void setShowRepaintCounter(bool show) { m_showRepaintCounter = show; }
    bool isShowingRepaintCounter() const { return m_showRepaintCounter; }

    // FIXME: this is really a paint count.
    int repaintCount() const { return m_repaintCount; }
    int incrementRepaintCount() { return ++m_repaintCount; }

    virtual void setDebugBackgroundColor(const Color&) { }
    virtual void setDebugBorder(const Color&, float /*borderWidth*/) { }

    enum class CustomAppearance : uint8_t {
        None,
        ScrollingOverhang,
        ScrollingShadow,
        LightBackdrop,
        DarkBackdrop
    };
    virtual void setCustomAppearance(CustomAppearance customAppearance) { m_customAppearance = customAppearance; }
    CustomAppearance customAppearance() const { return m_customAppearance; }

    // z-position is the z-equivalent of position(). It's only used for debugging purposes.
    virtual float zPosition() const { return m_zPosition; }
    WEBCORE_EXPORT virtual void setZPosition(float);

    virtual FloatSize pixelAlignmentOffset() const { return FloatSize(); }
    
    virtual void setAppliesPageScale(bool appliesScale = true) { m_appliesPageScale = appliesScale; }
    virtual bool appliesPageScale() const { return m_appliesPageScale; }

    float pageScaleFactor() const { return client().pageScaleFactor(); }
    float deviceScaleFactor() const { return client().deviceScaleFactor(); }
    
    // Whether this layer can throw away backing store to save memory. False for layers that can be revealed by async scrolling.
    virtual void setAllowsBackingStoreDetaching(bool) { }
    virtual bool allowsBackingStoreDetaching() const { return true; }

    virtual void deviceOrPageScaleFactorChanged() { }
    WEBCORE_EXPORT void noteDeviceOrPageScaleFactorChangedIncludingDescendants();

    void setIsInWindow(bool);

    // Some compositing systems may do internal batching to synchronize compositing updates
    // with updates drawn into the window. These methods flush internal batched state on this layer
    // and descendant layers, and this layer only.
    virtual void flushCompositingState(const FloatRect& /* clipRect */) { }
    virtual void flushCompositingStateForThisLayerOnly() { }

    // If the exposed rect of this layer changes, returns true if this or descendant layers need a flush,
    // for example to allocate new tiles.
    virtual bool visibleRectChangeRequiresFlush(const FloatRect& /* clipRect */) const { return false; }

    static FloatRect adjustCoverageRectForMovement(const FloatRect& coverageRect, const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect);

    // Return a string with a human readable form of the layer tree, If debug is true
    // pointers for the layers and timing data will be included in the returned string.
    WEBCORE_EXPORT String layerTreeAsText(OptionSet<LayerTreeAsTextOptions> = { }) const;

    // For testing.
    virtual String displayListAsText(DisplayList::AsTextFlags) const { return String(); }

    virtual String platformLayerTreeAsText(OptionSet<PlatformLayerTreeAsTextFlags>) const { return String(); }

    virtual void setIsTrackingDisplayListReplay(bool isTracking) { m_isTrackingDisplayListReplay = isTracking; }
    virtual bool isTrackingDisplayListReplay() const { return m_isTrackingDisplayListReplay; }
    virtual String replayDisplayListAsText(DisplayList::AsTextFlags) const { return String(); }

    // Return an estimate of the backing store memory cost (in bytes). May be incorrect for tiled layers.
    WEBCORE_EXPORT virtual double backingStoreMemoryEstimate() const;

    virtual bool backingStoreAttached() const { return true; }
    virtual bool backingStoreAttachedForTesting() const { return backingStoreAttached(); }

    virtual TiledBacking* tiledBacking() const { return 0; }

    void resetTrackedRepaints();
    void addRepaintRect(const FloatRect&);

    static bool supportsRoundedClip();
    static bool supportsBackgroundColorContent();
    static bool supportsLayerType(Type);
    static bool supportsContentsTiling();
    static bool supportsSubpixelAntialiasedLayerText();

    void updateDebugIndicators();

    virtual bool isGraphicsLayerCA() const { return false; }
    virtual bool isGraphicsLayerCARemote() const { return false; }
    virtual bool isGraphicsLayerTextureMapper() const { return false; }
    virtual bool isCoordinatedGraphicsLayer() const { return false; }

    const std::optional<FloatRect>& animationExtent() const { return m_animationExtent; }
    void setAnimationExtent(std::optional<FloatRect> animationExtent) { m_animationExtent = animationExtent; }

    static void traverse(GraphicsLayer&, const Function<void(GraphicsLayer&)>&);

protected:
    WEBCORE_EXPORT explicit GraphicsLayer(Type, GraphicsLayerClient&);

    // Should be called from derived class destructors. Should call willBeDestroyed() on super.
    WEBCORE_EXPORT void willBeDestroyed();
    bool beingDestroyed() const { return m_beingDestroyed; }

    // This method is used by platform GraphicsLayer classes to clear the filters
    // when compositing is not done in hardware. It is not virtual, so the caller
    // needs to notifiy the change to the platform layer as needed.
    void clearFilters() { m_filters.clear(); }
    void clearBackdropFilters() { m_backdropFilters.clear(); }

    // Given a KeyframeValueList containing filterOperations, return true if the operations are valid.
    static int validateFilterOperations(const KeyframeValueList&);

    // Given a list of TransformAnimationValues, see if all the operations for each keyframe match. If so
    // return the index of the KeyframeValueList entry that has that list of operations (it may not be
    // the first entry because some keyframes might have an empty transform and those match any list).
    // If the lists don't match return -1. On return, if hasBigRotation is true, functions contain 
    // rotations of >= 180 degrees
    static int validateTransformOperations(const KeyframeValueList&, bool& hasBigRotation);

    virtual bool shouldRepaintOnSizeChange() const { return drawsContent(); }

    void removeFromParentInternal();

    // The layer being replicated.
    GraphicsLayer* replicatedLayer() const { return m_replicatedLayer; }
    virtual void setReplicatedLayer(GraphicsLayer* layer) { m_replicatedLayer = layer; }

#if HAVE(CORE_ANIMATION_SEPARATED_LAYERS)
#if HAVE(CORE_ANIMATION_SEPARATED_PORTALS)
    bool isDescendentOfSeparatedPortal() const { return m_isDescendentOfSeparatedPortal; }
    virtual void setIsDescendentOfSeparatedPortal(bool b) { m_isDescendentOfSeparatedPortal = b; }
#endif
#endif


    void dumpProperties(WTF::TextStream&, OptionSet<LayerTreeAsTextOptions>) const;
    virtual void dumpAdditionalProperties(WTF::TextStream&, OptionSet<LayerTreeAsTextOptions>) const { }

    WEBCORE_EXPORT virtual void getDebugBorderInfo(Color&, float& width) const;

    GraphicsLayerClient* m_client; // Always non-null.
    String m_name;
    
    // Offset from the owning renderer
    FloatSize m_offsetFromRenderer;
    
    // Scroll offset of the content layer inside its scrolling parent layer.
    ScrollOffset m_scrollOffset;

    // Position is relative to the parent GraphicsLayer
    FloatPoint m_position;

    // If set, overrides m_position. Only used for coverage computation.
    std::optional<FloatPoint> m_approximatePosition;

    FloatPoint3D m_anchorPoint { 0.5f, 0.5f, 0 };
    FloatSize m_size;
    FloatPoint m_boundsOrigin;

    std::unique_ptr<TransformationMatrix> m_transform;
    std::unique_ptr<TransformationMatrix> m_childrenTransform;

    Color m_backgroundColor;
    float m_opacity { 1 };
    float m_zPosition { 0 };
    
    FilterOperations m_filters;
    FilterOperations m_backdropFilters;
    
#if ENABLE(SCROLLING_THREAD)
    ScrollingNodeID m_scrollingNodeID { 0 };
#endif

#if ENABLE(CSS_COMPOSITING)
    BlendMode m_blendMode { BlendMode::Normal };
#endif

    const Type m_type;
    CustomAppearance m_customAppearance { CustomAppearance::None };
    OptionSet<GraphicsLayerPaintingPhase> m_paintingPhase { GraphicsLayerPaintingPhase::Foreground, GraphicsLayerPaintingPhase::Background };
    CompositingCoordinatesOrientation m_contentsOrientation { CompositingCoordinatesOrientation::TopDown }; // affects orientation of layer contents

    bool m_beingDestroyed : 1;
    bool m_contentsOpaque : 1;
    bool m_supportsSubpixelAntialiasedText : 1;
    bool m_preserves3D: 1;
    bool m_backfaceVisibility : 1;
    bool m_masksToBounds : 1;
    bool m_drawsContent : 1;
    bool m_contentsVisible : 1;
    bool m_contentsRectClipsDescendants : 1;
    bool m_acceleratesDrawing : 1;
    bool m_usesDisplayListDrawing : 1;
    bool m_appliesPageScale : 1; // Set for the layer which has the page scale applied to it.
    bool m_showDebugBorder : 1;
    bool m_showRepaintCounter : 1;
    bool m_isMaskLayer : 1;
    bool m_isTrackingDisplayListReplay : 1;
    bool m_userInteractionEnabled : 1;
    bool m_canDetachBackingStore : 1;
#if HAVE(CORE_ANIMATION_SEPARATED_LAYERS)
    bool m_isSeparated : 1;
#if HAVE(CORE_ANIMATION_SEPARATED_PORTALS)
    bool m_isSeparatedPortal : 1;
    bool m_isDescendentOfSeparatedPortal : 1;
#endif
#endif

    int m_repaintCount { 0 };

    Vector<Ref<GraphicsLayer>> m_children;
    GraphicsLayer* m_parent { nullptr };

    RefPtr<GraphicsLayer> m_maskLayer { nullptr }; // Reference to mask layer.

    RefPtr<GraphicsLayer> m_replicaLayer { nullptr }; // A layer that replicates this layer. We only allow one, for now.
                                   // The replica is not parented; this is the primary reference to it.
    GraphicsLayer* m_replicatedLayer { nullptr }; // For a replica layer, a reference to the original layer.
    FloatPoint m_replicatedLayerPosition; // For a replica layer, the position of the replica.

    FloatRect m_contentsRect;
    FloatRoundedRect m_contentsClippingRect;
    FloatRoundedRect m_masksToBoundsRect;
    FloatSize m_contentsTilePhase;
    FloatSize m_contentsTileSize;
    ScalingFilter m_contentsMinificationFilter = ScalingFilter::Linear;
    ScalingFilter m_contentsMagnificationFilter = ScalingFilter::Linear;
    FloatRoundedRect m_backdropFiltersRect;
    std::optional<FloatRect> m_animationExtent;

    EventRegion m_eventRegion;
#if USE(CA)
    WindRule m_shapeLayerWindRule { WindRule::NonZero };
    Path m_shapeLayerPath;
#endif
};

WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const WebCore::GraphicsLayerPaintingPhase);
WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const Vector<GraphicsLayer::PlatformLayerID>&);
WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const GraphicsLayer::CustomAppearance&);

} // namespace WebCore

#define SPECIALIZE_TYPE_TRAITS_GRAPHICSLAYER(ToValueTypeName, predicate) \
SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \
    static bool isType(const WebCore::GraphicsLayer& layer) { return layer.predicate; } \
SPECIALIZE_TYPE_TRAITS_END()

#if ENABLE(TREE_DEBUGGING)
// Outside the WebCore namespace for ease of invocation from the debugger.
void showGraphicsLayerTree(const WebCore::GraphicsLayer* layer);
#endif

namespace WTF {

template<> struct EnumTraits<WebCore::GraphicsLayer::CustomAppearance> {
    using values = EnumValues<
        WebCore::GraphicsLayer::CustomAppearance,
        WebCore::GraphicsLayer::CustomAppearance::None,
        WebCore::GraphicsLayer::CustomAppearance::ScrollingOverhang,
        WebCore::GraphicsLayer::CustomAppearance::ScrollingShadow,
        WebCore::GraphicsLayer::CustomAppearance::LightBackdrop,
        WebCore::GraphicsLayer::CustomAppearance::DarkBackdrop
    >;
};

} // namespace WTF
