| /* |
| * 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 |