/*
 * 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 {
enum class AsTextFlag : uint8_t;
}

// 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)
    enum class ModelInteraction : uint8_t { Enabled, Disabled };
    virtual void setContentsToModel(RefPtr<Model>&&, ModelInteraction) { }
    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
    };
    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 setAllowsTiling(bool allowsTiling) { m_allowsTiling = allowsTiling; }
    virtual bool allowsTiling() const { return m_allowsTiling; }

    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(OptionSet<DisplayList::AsTextFlag>) 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(OptionSet<DisplayList::AsTextFlag>) 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&);

    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_allowsTiling : 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
    >;
};

} // namespace WTF
