/* * Copyright (C) 2009, 2014 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. */ #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 #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; } // 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() { } double keyTime() const { return m_keyTime; } const TimingFunction* timingFunction() const { return m_timingFunction.get(); } virtual std::unique_ptr 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 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) { } virtual std::unique_ptr clone() const override { return std::make_unique(*this); } FloatAnimationValue(const FloatAnimationValue& other) : AnimationValue(other) , m_value(other.m_value) { } 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) { } virtual std::unique_ptr clone() const override { return std::make_unique(*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; }; // 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) { } virtual std::unique_ptr clone() const override { return std::make_unique(*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; }; // 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()) { 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); } // Insert, sorted by keyTime. WEBCORE_EXPORT void insert(std::unique_ptr); protected: Vector> 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 { WTF_MAKE_NONCOPYABLE(GraphicsLayer); WTF_MAKE_FAST_ALLOCATED; public: enum class Type { Normal, PageTiledBacking, Scrolling, Shape }; WEBCORE_EXPORT static std::unique_ptr 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; } // 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; } 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& children() const { return m_children; } // Returns true if the child list changed. WEBCORE_EXPORT virtual bool setChildren(const Vector&); enum ContentsLayerPurpose { NoContentsLayer = 0, ContentsLayerForImage, ContentsLayerForMedia, ContentsLayerForCanvas, ContentsLayerForBackgroundColor, ContentsLayerForPlugin }; // Add child layers. If the child is already parented, it will be removed from its old parent. 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(); // The parent() of a maskLayer is set to the layer being masked. GraphicsLayer* maskLayer() const { return m_maskLayer; } virtual void setMaskLayer(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(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; } 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); // 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_position = 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 { 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 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(); } // 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 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 FloatRect& backdropFiltersRect) { m_backdropFiltersRect = backdropFiltersRect; } FloatRect 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 GraphicsLayerPaintingPhase paintingPhase() const { return m_paintingPhase; } void setPaintingPhase(GraphicsLayerPaintingPhase phase) { m_paintingPhase = phase; } 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; } // Set a rounded rect that is used to clip this layer and its descendants (implies setting masksToBounds). // Returns false if the platform can't support this rounded clip, and we should fall back to painting a mask. 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); // 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. If this returns // false, the animation will be run by AnimationController. // These methods handle both transitions and keyframe animations. 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*/) { } WEBCORE_EXPORT virtual void suspendAnimations(double time); WEBCORE_EXPORT virtual void resumeAnimations(); // Layer contents virtual void setContentsToImage(Image*) { } virtual bool shouldDirectlyCompositeImage(Image*) const { return true; } #if PLATFORM(IOS) virtual PlatformLayer* contentsLayerForMedia() const { return 0; } #endif // Pass an invalid color to remove the contents layer. virtual void setContentsToSolidColor(const Color&) { } virtual void setContentsToPlatformLayer(PlatformLayer*, ContentsLayerPurpose) { } virtual bool usesContentsLayer() const { return false; } // Callback from the underlying graphics system to draw layer contents. void paintGraphicsLayerContents(GraphicsContext&, const FloatRect& clip); // For hosting this GraphicsLayer in a native layer hierarchy. virtual PlatformLayer* platformLayer() const { return 0; } enum CompositingCoordinatesOrientation { CompositingCoordinatesTopDown, CompositingCoordinatesBottomUp }; // 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; } 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; } // 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 CustomAppearance { NoCustomAppearance, ScrollingOverhang, ScrollingShadow, LightBackdropAppearance, DarkBackdropAppearance }; 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); 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(); } // Whether this layer is viewport constrained, implying that it's moved around externally from GraphicsLayer (e.g. by the scrolling tree). virtual void setIsViewportConstrained(bool) { } virtual bool isViewportConstrained() const { return false; } virtual void deviceOrPageScaleFactorChanged() { } WEBCORE_EXPORT void noteDeviceOrPageScaleFactorChangedIncludingDescendants(); // 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 */, bool /* viewportIsStable */) { } virtual void flushCompositingStateForThisLayerOnly(bool /* viewportIsStable */) { } // 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; } // 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(LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const; // For testing. 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(); } // Return an estimate of the backing store memory cost (in bytes). May be incorrect for tiled layers. 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; } protected: WEBCORE_EXPORT explicit GraphicsLayer(Type, GraphicsLayerClient&); // Should be called from derived class destructors. Should call willBeDestroyed() on super. WEBCORE_EXPORT virtual void willBeDestroyed(); // 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(); } virtual void setOpacityInternal(float) { } // The layer being replicated. 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 /*indent*/, LayerTreeAsTextBehavior) const { } WEBCORE_EXPORT virtual void getDebugBorderInfo(Color&, float& width) const; GraphicsLayerClient& m_client; String m_name; // Offset from the owning renderer FloatSize m_offsetFromRenderer; // Position is relative to the parent GraphicsLayer 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; // 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; GraphicsLayerPaintingPhase m_paintingPhase; CompositingCoordinatesOrientation m_contentsOrientation; // affects orientation of layer contents Vector m_children; GraphicsLayer* m_parent; GraphicsLayer* m_maskLayer; // Reference to mask layer. We don't own this. GraphicsLayer* m_replicaLayer; // 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; // 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; FloatRect 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&); WEBCORE_EXPORT TextStream& operator<<(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() #ifndef NDEBUG // Outside the WebCore namespace for ease of invocation from gdb. void showGraphicsLayerTree(const WebCore::GraphicsLayer* layer); #endif #endif // GraphicsLayer_h