blob: bf9509f18ccb959923dd9f5d5fb252be18b9899c [file] [log] [blame]
/*
* 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 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) { }
#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