#ifndef GraphicsLayer_h
#define GraphicsLayer_h
#include "Animation.h"
#include "Color.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 "TransformOperations.h"
#include "WindRule.h"
#include <wtf/TypeCasts.h>
#if ENABLE(CSS_COMPOSITING)
#include "GraphicsTypes.h"
#endif
namespace WebCore {
class GraphicsContext;
class GraphicsLayerFactory;
class Image;
class TextStream;
class TiledBacking;
class TimingFunction;
class TransformationMatrix;
namespace DisplayList {
typedef unsigned AsTextFlags;
}
class AnimationValue {
WTF_MAKE_FAST_ALLOCATED;
public:
virtual ~AnimationValue() { }
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 ? other.m_timingFunction->clone() : nullptr)
{
}
private:
double m_keyTime;
RefPtr<TimingFunction> m_timingFunction;
};
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 std::make_unique<FloatAnimationValue>(*this);
}
FloatAnimationValue(const FloatAnimationValue& other)
: AnimationValue(other)
, m_value(other.m_value)
{
}
float value() const { return m_value; }
private:
float m_value;
};
class TransformAnimationValue : public AnimationValue {
public:
TransformAnimationValue(double keyTime, const TransformOperations& value, TimingFunction* timingFunction = nullptr)
: AnimationValue(keyTime, timingFunction)
, m_value(value)
{
}
std::unique_ptr<AnimationValue> clone() const override
{
return std::make_unique<TransformAnimationValue>(*this);
}
TransformAnimationValue(const TransformAnimationValue& other)
: AnimationValue(other)
{
for (size_t i = 0; i < other.m_value.operations().size(); ++i)
m_value.operations().append(other.m_value.operations()[i]->clone());
}
const TransformOperations& value() const { return m_value; }
private:
TransformOperations m_value;
};
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 std::make_unique<FilterAnimationValue>(*this);
}
FilterAnimationValue(const FilterAnimationValue& other)
: AnimationValue(other)
{
for (size_t i = 0; i < other.m_value.operations().size(); ++i)
m_value.operations().append(other.m_value.operations()[i]->clone());
}
const FilterOperations& value() const { return m_value; }
private:
FilterOperations m_value;
};
class KeyframeValueList {
public:
explicit KeyframeValueList(AnimatedPropertyID property)
: m_property(property)
{
}
KeyframeValueList(const KeyframeValueList& other)
: m_property(other.property())
{
for (size_t i = 0; i < other.m_values.size(); ++i)
m_values.append(other.m_values[i]->clone());
}
~KeyframeValueList()
{
}
KeyframeValueList& operator=(const KeyframeValueList& other)
{
KeyframeValueList copy(other);
swap(copy);
return *this;
}
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); }
WEBCORE_EXPORT void insert(std::unique_ptr<const AnimationValue>);
protected:
Vector<std::unique_ptr<const AnimationValue>> m_values;
AnimatedPropertyID m_property;
};
class GraphicsLayer {
WTF_MAKE_NONCOPYABLE(GraphicsLayer); WTF_MAKE_FAST_ALLOCATED;
public:
enum class Type {
Normal,
PageTiledBacking,
Scrolling,
Shape
};
WEBCORE_EXPORT static std::unique_ptr<GraphicsLayer> create(GraphicsLayerFactory*, GraphicsLayerClient&, Type = Type::Normal);
WEBCORE_EXPORT virtual ~GraphicsLayer();
Type type() const { return m_type; }
virtual void initialize(Type) { }
typedef uint64_t PlatformLayerID;
virtual PlatformLayerID primaryLayerID() const { return 0; }
GraphicsLayerClient& client() const { return m_client; }
const String& name() const { return m_name; }
virtual void setName(const String& name) { m_name = name; }
GraphicsLayer* parent() const { return m_parent; };
void setParent(GraphicsLayer*);
bool hasAncestor(GraphicsLayer*) const;
const Vector<GraphicsLayer*>& children() const { return m_children; }
WEBCORE_EXPORT virtual bool setChildren(const Vector<GraphicsLayer*>&);
enum ContentsLayerPurpose {
NoContentsLayer = 0,
ContentsLayerForImage,
ContentsLayerForMedia,
ContentsLayerForCanvas,
ContentsLayerForBackgroundColor,
ContentsLayerForPlugin
};
WEBCORE_EXPORT virtual void addChild(GraphicsLayer*);
WEBCORE_EXPORT virtual void addChildAtIndex(GraphicsLayer*, int index);
WEBCORE_EXPORT virtual void addChildAbove(GraphicsLayer*, GraphicsLayer* sibling);
WEBCORE_EXPORT virtual void addChildBelow(GraphicsLayer*, GraphicsLayer* sibling);
WEBCORE_EXPORT virtual bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild);
WEBCORE_EXPORT void removeAllChildren();
WEBCORE_EXPORT virtual void removeFromParent();
GraphicsLayer* maskLayer() const { return m_maskLayer; }
virtual void setMaskLayer(GraphicsLayer*);
void setIsMaskLayer(bool isMask) { m_isMaskLayer = isMask; }
bool isMaskLayer() const { return m_isMaskLayer; }
WEBCORE_EXPORT virtual void setReplicatedByLayer(GraphicsLayer*);
bool isReplicated() const { return m_replicaLayer; }
GraphicsLayer* replicaLayer() const { return m_replicaLayer; }
const FloatPoint& replicatedLayerPosition() const { return m_replicatedLayerPosition; }
void setReplicatedLayerPosition(const FloatPoint& p) { m_replicatedLayerPosition = p; }
enum ShouldSetNeedsDisplay {
DontSetNeedsDisplay,
SetNeedsDisplay
};
FloatSize offsetFromRenderer() const { return m_offsetFromRenderer; }
void setOffsetFromRenderer(const FloatSize&, ShouldSetNeedsDisplay = SetNeedsDisplay);
const FloatPoint& position() const { return m_position; }
virtual void setPosition(const FloatPoint& p) { m_position = p; }
virtual void syncPosition(const FloatPoint& p) { m_position = p; }
const FloatPoint3D& anchorPoint() const { return m_anchorPoint; }
virtual void setAnchorPoint(const FloatPoint3D& p) { m_anchorPoint = p; }
const FloatSize& size() const { return m_size; }
WEBCORE_EXPORT virtual void setSize(const FloatSize&);
const FloatPoint& boundsOrigin() const { return m_boundsOrigin; }
virtual void setBoundsOrigin(const FloatPoint& origin) { m_boundsOrigin = origin; }
virtual void syncBoundsOrigin(const FloatPoint& origin) { m_boundsOrigin = origin; }
const TransformationMatrix& transform() const { return m_transform; }
virtual void setTransform(const TransformationMatrix& t) { m_transform = t; }
const TransformationMatrix& childrenTransform() const { return m_childrenTransform; }
virtual void setChildrenTransform(const TransformationMatrix& t) { m_childrenTransform = t; }
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; }
bool needsBackdrop() const { return !m_backdropFilters.isEmpty(); }
const Color& backgroundColor() const { return m_backgroundColor; }
WEBCORE_EXPORT virtual void setBackgroundColor(const Color&);
bool contentsOpaque() const { return m_contentsOpaque; }
virtual void setContentsOpaque(bool b) { m_contentsOpaque = 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; }
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
GraphicsLayerPaintingPhase paintingPhase() const { return m_paintingPhase; }
void setPaintingPhase(GraphicsLayerPaintingPhase phase) { m_paintingPhase = phase; }
enum ShouldClipToLayer {
DoNotClipToLayer,
ClipToLayer
};
virtual void setNeedsDisplay() = 0;
virtual void setNeedsDisplayInRect(const FloatRect&, ShouldClipToLayer = ClipToLayer) = 0;
virtual void setContentsNeedsDisplay() { };
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(); }
FloatRect contentsRect() const { return m_contentsRect; }
virtual void setContentsRect(const FloatRect& r) { m_contentsRect = r; }
FloatRoundedRect contentsClippingRect() const { return m_contentsClippingRect; }
virtual void setContentsClippingRect(const FloatRoundedRect& roundedRect) { m_contentsClippingRect = roundedRect; }
FloatRoundedRect maskToBoundsRect() const { return m_masksToBoundsRect; };
virtual bool setMasksToBoundsRect(const FloatRoundedRect& roundedRect) { m_masksToBoundsRect = roundedRect; return false; }
Path shapeLayerPath() const;
virtual void setShapeLayerPath(const Path&);
WindRule shapeLayerWindRule() const;
virtual void setShapeLayerWindRule(WindRule);
static String animationNameForTransition(AnimatedPropertyID);
virtual bool addAnimation(const KeyframeValueList&, const FloatSize& , const Animation*, const String& , double ) { return false; }
virtual void pauseAnimation(const String& , double ) { }
virtual void removeAnimation(const String& ) { }
WEBCORE_EXPORT virtual void suspendAnimations(double time);
WEBCORE_EXPORT virtual void resumeAnimations();
virtual void setContentsToImage(Image*) { }
virtual bool shouldDirectlyCompositeImage(Image*) const { return true; }
#if PLATFORM(IOS)
virtual PlatformLayer* contentsLayerForMedia() const { return 0; }
#endif
virtual void setContentsToSolidColor(const Color&) { }
virtual void setContentsToPlatformLayer(PlatformLayer*, ContentsLayerPurpose) { }
virtual bool usesContentsLayer() const { return false; }
void paintGraphicsLayerContents(GraphicsContext&, const FloatRect& clip);
virtual PlatformLayer* platformLayer() const { return 0; }
enum CompositingCoordinatesOrientation { CompositingCoordinatesTopDown, CompositingCoordinatesBottomUp };
virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation) { m_contentsOrientation = orientation; }
CompositingCoordinatesOrientation contentsOrientation() const { return m_contentsOrientation; }
void dumpLayer(TextStream&, int indent = 0, LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) 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; }
int repaintCount() const { return m_repaintCount; }
int incrementRepaintCount() { return ++m_repaintCount; }
virtual void setDebugBackgroundColor(const Color&) { }
virtual void setDebugBorder(const Color&, float ) { }
enum CustomAppearance { NoCustomAppearance, ScrollingOverhang, ScrollingShadow, LightBackdropAppearance, DarkBackdropAppearance };
virtual void setCustomAppearance(CustomAppearance customAppearance) { m_customAppearance = customAppearance; }
CustomAppearance customAppearance() const { return m_customAppearance; }
virtual float zPosition() const { return m_zPosition; }
WEBCORE_EXPORT virtual void setZPosition(float);
WEBCORE_EXPORT virtual void distributeOpacity(float);
WEBCORE_EXPORT virtual float accumulatedOpacity() const;
#if PLATFORM(IOS)
bool hasFlattenedPerspectiveTransform() const { return !preserves3D() && m_childrenTransform.hasPerspective(); }
#endif
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 m_client.pageScaleFactor(); }
float deviceScaleFactor() const { return m_client.deviceScaleFactor(); }
virtual void setIsViewportConstrained(bool) { }
virtual bool isViewportConstrained() const { return false; }
virtual void deviceOrPageScaleFactorChanged() { }
WEBCORE_EXPORT void noteDeviceOrPageScaleFactorChangedIncludingDescendants();
virtual void flushCompositingState(const FloatRect& , bool ) { }
virtual void flushCompositingStateForThisLayerOnly(bool ) { }
virtual bool visibleRectChangeRequiresFlush(const FloatRect& ) const { return false; }
WEBCORE_EXPORT String layerTreeAsText(LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const;
WEBCORE_EXPORT virtual String displayListAsText(DisplayList::AsTextFlags) const { return String(); }
WEBCORE_EXPORT virtual void setIsTrackingDisplayListReplay(bool isTracking) { m_isTrackingDisplayListReplay = isTracking; }
WEBCORE_EXPORT virtual bool isTrackingDisplayListReplay() const { return m_isTrackingDisplayListReplay; }
WEBCORE_EXPORT virtual String replayDisplayListAsText(DisplayList::AsTextFlags) const { return String(); }
WEBCORE_EXPORT virtual double backingStoreMemoryEstimate() const;
bool usingTiledBacking() const { return m_usingTiledBacking; }
virtual TiledBacking* tiledBacking() const { return 0; }
void resetTrackedRepaints();
void addRepaintRect(const FloatRect&);
static bool supportsBackgroundColorContent();
static bool supportsLayerType(Type);
static bool supportsContentsTiling();
void updateDebugIndicators();
virtual bool canThrottleLayerFlush() const { return false; }
virtual bool isGraphicsLayerCA() const { return false; }
virtual bool isGraphicsLayerCARemote() const { return false; }
virtual bool isGraphicsLayerTextureMapper() const { return false; }
virtual bool isCoordinatedGraphicsLayer() const { return false; }
protected:
WEBCORE_EXPORT explicit GraphicsLayer(Type, GraphicsLayerClient&);
WEBCORE_EXPORT virtual void willBeDestroyed();
void clearFilters() { m_filters.clear(); }
void clearBackdropFilters() { m_backdropFilters.clear(); }
static int validateFilterOperations(const KeyframeValueList&);
static int validateTransformOperations(const KeyframeValueList&, bool& hasBigRotation);
virtual bool shouldRepaintOnSizeChange() const { return drawsContent(); }
virtual void setOpacityInternal(float) { }
GraphicsLayer* replicatedLayer() const { return m_replicatedLayer; }
virtual void setReplicatedLayer(GraphicsLayer* layer) { m_replicatedLayer = layer; }
void dumpProperties(TextStream&, int indent, LayerTreeAsTextBehavior) const;
virtual void dumpAdditionalProperties(TextStream&, int , LayerTreeAsTextBehavior) const { }
WEBCORE_EXPORT virtual void getDebugBorderInfo(Color&, float& width) const;
GraphicsLayerClient& m_client;
String m_name;
FloatSize m_offsetFromRenderer;
FloatPoint m_position;
FloatPoint3D m_anchorPoint;
FloatSize m_size;
FloatPoint m_boundsOrigin;
TransformationMatrix m_transform;
TransformationMatrix m_childrenTransform;
Color m_backgroundColor;
float m_opacity;
float m_zPosition;
FilterOperations m_filters;
FilterOperations m_backdropFilters;
#if ENABLE(CSS_COMPOSITING)
BlendMode m_blendMode;
#endif
const Type m_type;
bool m_contentsOpaque : 1;
bool m_preserves3D: 1;
bool m_backfaceVisibility : 1;
bool m_usingTiledBacking : 1;
bool m_masksToBounds : 1;
bool m_drawsContent : 1;
bool m_contentsVisible : 1;
bool m_acceleratesDrawing : 1;
bool m_usesDisplayListDrawing : 1;
bool m_appliesPageScale : 1; bool m_showDebugBorder : 1;
bool m_showRepaintCounter : 1;
bool m_isMaskLayer : 1;
bool m_isTrackingDisplayListReplay : 1;
bool m_userInteractionEnabled : 1;
GraphicsLayerPaintingPhase m_paintingPhase;
CompositingCoordinatesOrientation m_contentsOrientation;
Vector<GraphicsLayer*> m_children;
GraphicsLayer* m_parent;
GraphicsLayer* m_maskLayer;
GraphicsLayer* m_replicaLayer; GraphicsLayer* m_replicatedLayer; FloatPoint m_replicatedLayerPosition;
FloatRect m_contentsRect;
FloatRoundedRect m_contentsClippingRect;
FloatRoundedRect m_masksToBoundsRect;
FloatSize m_contentsTilePhase;
FloatSize m_contentsTileSize;
FloatRoundedRect m_backdropFiltersRect;
int m_repaintCount;
CustomAppearance m_customAppearance;
#if USE(CA)
Path m_shapeLayerPath;
WindRule m_shapeLayerWindRule { RULE_NONZERO };
#endif
};
WEBCORE_EXPORT TextStream& operator<<(TextStream&, const Vector<GraphicsLayer::PlatformLayerID>&);
WEBCORE_EXPORT TextStream& operator<<(TextStream&, const GraphicsLayer::CustomAppearance&);
}
#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)
void showGraphicsLayerTree(const WebCore::GraphicsLayer* layer);
#endif
#endif // GraphicsLayer_h