| 1 | /* |
| 2 | * Copyright (C) 2009-2017 Apple Inc. All rights reserved. |
| 3 | * |
| 4 | * Redistribution and use in source and binary forms, with or without |
| 5 | * modification, are permitted provided that the following conditions |
| 6 | * are met: |
| 7 | * 1. Redistributions of source code must retain the above copyright |
| 8 | * notice, this list of conditions and the following disclaimer. |
| 9 | * 2. Redistributions in binary form must reproduce the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer in the |
| 11 | * documentation and/or other materials provided with the distribution. |
| 12 | * |
| 13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 | */ |
| 25 | |
| 26 | #pragma once |
| 27 | |
| 28 | #include "Animation.h" |
| 29 | #include "Color.h" |
| 30 | #include "EventRegion.h" |
| 31 | #include "FilterOperations.h" |
| 32 | #include "FloatPoint.h" |
| 33 | #include "FloatPoint3D.h" |
| 34 | #include "FloatRoundedRect.h" |
| 35 | #include "FloatSize.h" |
| 36 | #include "GraphicsLayerClient.h" |
| 37 | #include "Path.h" |
| 38 | #include "PlatformLayer.h" |
| 39 | #include "Region.h" |
| 40 | #include "ScrollableArea.h" |
| 41 | #include "TransformOperations.h" |
| 42 | #include "WindRule.h" |
| 43 | #include <wtf/Function.h> |
| 44 | #include <wtf/TypeCasts.h> |
| 45 | |
| 46 | #if ENABLE(CSS_COMPOSITING) |
| 47 | #include "GraphicsTypes.h" |
| 48 | #endif |
| 49 | |
| 50 | namespace WTF { |
| 51 | class TextStream; |
| 52 | } |
| 53 | |
| 54 | namespace WebCore { |
| 55 | |
| 56 | class GraphicsContext; |
| 57 | class GraphicsLayerFactory; |
| 58 | class Image; |
| 59 | class TiledBacking; |
| 60 | class TimingFunction; |
| 61 | class TransformationMatrix; |
| 62 | |
| 63 | namespace DisplayList { |
| 64 | typedef unsigned AsTextFlags; |
| 65 | } |
| 66 | |
| 67 | // Base class for animation values (also used for transitions). Here to |
| 68 | // represent values for properties being animated via the GraphicsLayer, |
| 69 | // without pulling in style-related data from outside of the platform directory. |
| 70 | // FIXME: Should be moved to its own header file. |
| 71 | class AnimationValue { |
| 72 | WTF_MAKE_FAST_ALLOCATED; |
| 73 | public: |
| 74 | virtual ~AnimationValue() = default; |
| 75 | |
| 76 | double keyTime() const { return m_keyTime; } |
| 77 | const TimingFunction* timingFunction() const { return m_timingFunction.get(); } |
| 78 | virtual std::unique_ptr<AnimationValue> clone() const = 0; |
| 79 | |
| 80 | protected: |
| 81 | AnimationValue(double keyTime, TimingFunction* timingFunction = nullptr) |
| 82 | : m_keyTime(keyTime) |
| 83 | , m_timingFunction(timingFunction) |
| 84 | { |
| 85 | } |
| 86 | |
| 87 | AnimationValue(const AnimationValue& other) |
| 88 | : m_keyTime(other.m_keyTime) |
| 89 | , m_timingFunction(other.m_timingFunction ? RefPtr<TimingFunction> { other.m_timingFunction->clone() } : nullptr) |
| 90 | { |
| 91 | } |
| 92 | |
| 93 | AnimationValue(AnimationValue&&) = default; |
| 94 | |
| 95 | private: |
| 96 | void operator=(const AnimationValue&) = delete; |
| 97 | |
| 98 | double m_keyTime; |
| 99 | RefPtr<TimingFunction> m_timingFunction; |
| 100 | }; |
| 101 | |
| 102 | // Used to store one float value of an animation. |
| 103 | // FIXME: Should be moved to its own header file. |
| 104 | class FloatAnimationValue : public AnimationValue { |
| 105 | public: |
| 106 | FloatAnimationValue(double keyTime, float value, TimingFunction* timingFunction = nullptr) |
| 107 | : AnimationValue(keyTime, timingFunction) |
| 108 | , m_value(value) |
| 109 | { |
| 110 | } |
| 111 | |
| 112 | std::unique_ptr<AnimationValue> clone() const override |
| 113 | { |
| 114 | return std::make_unique<FloatAnimationValue>(*this); |
| 115 | } |
| 116 | |
| 117 | float value() const { return m_value; } |
| 118 | |
| 119 | private: |
| 120 | float m_value; |
| 121 | }; |
| 122 | |
| 123 | // Used to store one transform value in a keyframe list. |
| 124 | // FIXME: Should be moved to its own header file. |
| 125 | class TransformAnimationValue : public AnimationValue { |
| 126 | public: |
| 127 | TransformAnimationValue(double keyTime, const TransformOperations& value, TimingFunction* timingFunction = nullptr) |
| 128 | : AnimationValue(keyTime, timingFunction) |
| 129 | , m_value(value) |
| 130 | { |
| 131 | } |
| 132 | |
| 133 | std::unique_ptr<AnimationValue> clone() const override |
| 134 | { |
| 135 | return std::make_unique<TransformAnimationValue>(*this); |
| 136 | } |
| 137 | |
| 138 | TransformAnimationValue(const TransformAnimationValue& other) |
| 139 | : AnimationValue(other) |
| 140 | { |
| 141 | m_value.operations().reserveInitialCapacity(other.m_value.operations().size()); |
| 142 | for (auto& operation : other.m_value.operations()) |
| 143 | m_value.operations().uncheckedAppend(operation->clone()); |
| 144 | } |
| 145 | |
| 146 | TransformAnimationValue(TransformAnimationValue&&) = default; |
| 147 | |
| 148 | const TransformOperations& value() const { return m_value; } |
| 149 | |
| 150 | private: |
| 151 | TransformOperations m_value; |
| 152 | }; |
| 153 | |
| 154 | // Used to store one filter value in a keyframe list. |
| 155 | // FIXME: Should be moved to its own header file. |
| 156 | class FilterAnimationValue : public AnimationValue { |
| 157 | public: |
| 158 | FilterAnimationValue(double keyTime, const FilterOperations& value, TimingFunction* timingFunction = nullptr) |
| 159 | : AnimationValue(keyTime, timingFunction) |
| 160 | , m_value(value) |
| 161 | { |
| 162 | } |
| 163 | |
| 164 | std::unique_ptr<AnimationValue> clone() const override |
| 165 | { |
| 166 | return std::make_unique<FilterAnimationValue>(*this); |
| 167 | } |
| 168 | |
| 169 | FilterAnimationValue(const FilterAnimationValue& other) |
| 170 | : AnimationValue(other) |
| 171 | { |
| 172 | m_value.operations().reserveInitialCapacity(other.m_value.operations().size()); |
| 173 | for (auto& operation : other.m_value.operations()) |
| 174 | m_value.operations().uncheckedAppend(operation->clone()); |
| 175 | } |
| 176 | |
| 177 | FilterAnimationValue(FilterAnimationValue&&) = default; |
| 178 | |
| 179 | const FilterOperations& value() const { return m_value; } |
| 180 | |
| 181 | private: |
| 182 | FilterOperations m_value; |
| 183 | }; |
| 184 | |
| 185 | // Used to store a series of values in a keyframe list. |
| 186 | // Values will all be of the same type, which can be inferred from the property. |
| 187 | // FIXME: Should be moved to its own header file. |
| 188 | class KeyframeValueList { |
| 189 | public: |
| 190 | explicit KeyframeValueList(AnimatedPropertyID property) |
| 191 | : m_property(property) |
| 192 | { |
| 193 | } |
| 194 | |
| 195 | KeyframeValueList(const KeyframeValueList& other) |
| 196 | : m_property(other.property()) |
| 197 | { |
| 198 | m_values.reserveInitialCapacity(other.m_values.size()); |
| 199 | for (auto& value : other.m_values) |
| 200 | m_values.uncheckedAppend(value->clone()); |
| 201 | } |
| 202 | |
| 203 | KeyframeValueList(KeyframeValueList&&) = default; |
| 204 | |
| 205 | KeyframeValueList& operator=(const KeyframeValueList& other) |
| 206 | { |
| 207 | KeyframeValueList copy(other); |
| 208 | swap(copy); |
| 209 | return *this; |
| 210 | } |
| 211 | |
| 212 | KeyframeValueList& operator=(KeyframeValueList&&) = default; |
| 213 | |
| 214 | void swap(KeyframeValueList& other) |
| 215 | { |
| 216 | std::swap(m_property, other.m_property); |
| 217 | m_values.swap(other.m_values); |
| 218 | } |
| 219 | |
| 220 | AnimatedPropertyID property() const { return m_property; } |
| 221 | |
| 222 | size_t size() const { return m_values.size(); } |
| 223 | const AnimationValue& at(size_t i) const { return *m_values.at(i); } |
| 224 | |
| 225 | // Insert, sorted by keyTime. |
| 226 | WEBCORE_EXPORT void insert(std::unique_ptr<const AnimationValue>); |
| 227 | |
| 228 | protected: |
| 229 | Vector<std::unique_ptr<const AnimationValue>> m_values; |
| 230 | AnimatedPropertyID m_property; |
| 231 | }; |
| 232 | |
| 233 | // GraphicsLayer is an abstraction for a rendering surface with backing store, |
| 234 | // which may have associated transformation and animations. |
| 235 | |
| 236 | class GraphicsLayer : public RefCounted<GraphicsLayer> { |
| 237 | WTF_MAKE_FAST_ALLOCATED; |
| 238 | public: |
| 239 | enum class Type : uint8_t { |
| 240 | Normal, |
| 241 | PageTiledBacking, |
| 242 | ScrollContainer, |
| 243 | Shape |
| 244 | }; |
| 245 | |
| 246 | WEBCORE_EXPORT static Ref<GraphicsLayer> create(GraphicsLayerFactory*, GraphicsLayerClient&, Type = Type::Normal); |
| 247 | |
| 248 | WEBCORE_EXPORT virtual ~GraphicsLayer(); |
| 249 | |
| 250 | // Unparent, clear the client, and clear the RefPtr. |
| 251 | WEBCORE_EXPORT static void unparentAndClear(RefPtr<GraphicsLayer>&); |
| 252 | // Clear the client, and clear the RefPtr, but leave parented. |
| 253 | WEBCORE_EXPORT static void clear(RefPtr<GraphicsLayer>&); |
| 254 | |
| 255 | WEBCORE_EXPORT void clearClient(); |
| 256 | WEBCORE_EXPORT void setClient(GraphicsLayerClient&); |
| 257 | |
| 258 | Type type() const { return m_type; } |
| 259 | |
| 260 | virtual void initialize(Type) { } |
| 261 | |
| 262 | using PlatformLayerID = uint64_t; |
| 263 | virtual PlatformLayerID primaryLayerID() const { return 0; } |
| 264 | |
| 265 | GraphicsLayerClient& client() const { return *m_client; } |
| 266 | |
| 267 | // Layer name. Only used to identify layers in debug output |
| 268 | const String& name() const { return m_name; } |
| 269 | virtual void setName(const String& name) { m_name = name; } |
| 270 | |
| 271 | GraphicsLayer* parent() const { return m_parent; }; |
| 272 | void setParent(GraphicsLayer*); // Internal use only. |
| 273 | |
| 274 | // Returns true if the layer has the given layer as an ancestor (excluding self). |
| 275 | bool hasAncestor(GraphicsLayer*) const; |
| 276 | |
| 277 | const Vector<Ref<GraphicsLayer>>& children() const { return m_children; } |
| 278 | Vector<Ref<GraphicsLayer>>& children() { return m_children; } |
| 279 | |
| 280 | // Returns true if the child list changed. |
| 281 | WEBCORE_EXPORT virtual bool setChildren(Vector<Ref<GraphicsLayer>>&&); |
| 282 | |
| 283 | // Add child layers. If the child is already parented, it will be removed from its old parent. |
| 284 | WEBCORE_EXPORT virtual void addChild(Ref<GraphicsLayer>&&); |
| 285 | WEBCORE_EXPORT virtual void addChildAtIndex(Ref<GraphicsLayer>&&, int index); |
| 286 | WEBCORE_EXPORT virtual void addChildAbove(Ref<GraphicsLayer>&&, GraphicsLayer* sibling); |
| 287 | WEBCORE_EXPORT virtual void addChildBelow(Ref<GraphicsLayer>&&, GraphicsLayer* sibling); |
| 288 | WEBCORE_EXPORT virtual bool replaceChild(GraphicsLayer* oldChild, Ref<GraphicsLayer>&& newChild); |
| 289 | |
| 290 | WEBCORE_EXPORT void removeAllChildren(); |
| 291 | WEBCORE_EXPORT virtual void removeFromParent(); |
| 292 | |
| 293 | // The parent() of a maskLayer is set to the layer being masked. |
| 294 | GraphicsLayer* maskLayer() const { return m_maskLayer.get(); } |
| 295 | virtual void setMaskLayer(RefPtr<GraphicsLayer>&&); |
| 296 | |
| 297 | void setIsMaskLayer(bool isMask) { m_isMaskLayer = isMask; } |
| 298 | bool isMaskLayer() const { return m_isMaskLayer; } |
| 299 | |
| 300 | // The given layer will replicate this layer and its children; the replica renders behind this layer. |
| 301 | WEBCORE_EXPORT virtual void setReplicatedByLayer(RefPtr<GraphicsLayer>&&); |
| 302 | // Whether this layer is being replicated by another layer. |
| 303 | bool isReplicated() const { return m_replicaLayer; } |
| 304 | // The layer that replicates this layer (if any). |
| 305 | GraphicsLayer* replicaLayer() const { return m_replicaLayer.get(); } |
| 306 | |
| 307 | const FloatPoint& replicatedLayerPosition() const { return m_replicatedLayerPosition; } |
| 308 | void setReplicatedLayerPosition(const FloatPoint& p) { m_replicatedLayerPosition = p; } |
| 309 | |
| 310 | enum ShouldSetNeedsDisplay { |
| 311 | DontSetNeedsDisplay, |
| 312 | SetNeedsDisplay |
| 313 | }; |
| 314 | |
| 315 | // Offset is origin of the renderer minus origin of the graphics layer. |
| 316 | FloatSize offsetFromRenderer() const { return m_offsetFromRenderer; } |
| 317 | void setOffsetFromRenderer(const FloatSize&, ShouldSetNeedsDisplay = SetNeedsDisplay); |
| 318 | |
| 319 | // Scroll offset of the content layer inside its scrolling parent layer. |
| 320 | ScrollOffset scrollOffset() const { return m_scrollOffset; } |
| 321 | void setScrollOffset(const ScrollOffset&, ShouldSetNeedsDisplay = SetNeedsDisplay); |
| 322 | |
| 323 | // The position of the layer (the location of its top-left corner in its parent) |
| 324 | const FloatPoint& position() const { return m_position; } |
| 325 | virtual void setPosition(const FloatPoint& p) { m_approximatePosition = WTF::nullopt; m_position = p; } |
| 326 | |
| 327 | // approximatePosition, if set, overrides position() and is used during coverage rect computation. |
| 328 | FloatPoint approximatePosition() const { return m_approximatePosition ? m_approximatePosition.value() : m_position; } |
| 329 | virtual void setApproximatePosition(const FloatPoint& p) { m_approximatePosition = p; } |
| 330 | |
| 331 | // For platforms that move underlying platform layers on a different thread for scrolling; just update the GraphicsLayer state. |
| 332 | virtual void syncPosition(const FloatPoint& p) { m_position = p; } |
| 333 | |
| 334 | // Anchor point: (0, 0) is top left, (1, 1) is bottom right. The anchor point |
| 335 | // affects the origin of the transforms. |
| 336 | const FloatPoint3D& anchorPoint() const { return m_anchorPoint; } |
| 337 | virtual void setAnchorPoint(const FloatPoint3D& p) { m_anchorPoint = p; } |
| 338 | |
| 339 | // The size of the layer. |
| 340 | const FloatSize& size() const { return m_size; } |
| 341 | WEBCORE_EXPORT virtual void setSize(const FloatSize&); |
| 342 | |
| 343 | // The boundOrigin affects the offset at which content is rendered, and sublayers are positioned. |
| 344 | const FloatPoint& boundsOrigin() const { return m_boundsOrigin; } |
| 345 | virtual void setBoundsOrigin(const FloatPoint& origin) { m_boundsOrigin = origin; } |
| 346 | |
| 347 | // For platforms that move underlying platform layers on a different thread for scrolling; just update the GraphicsLayer state. |
| 348 | virtual void syncBoundsOrigin(const FloatPoint& origin) { m_boundsOrigin = origin; } |
| 349 | |
| 350 | const TransformationMatrix& transform() const; |
| 351 | virtual void setTransform(const TransformationMatrix&); |
| 352 | bool hasNonIdentityTransform() const { return m_transform && !m_transform->isIdentity(); } |
| 353 | |
| 354 | const TransformationMatrix& childrenTransform() const; |
| 355 | virtual void setChildrenTransform(const TransformationMatrix&); |
| 356 | bool hasNonIdentityChildrenTransform() const { return m_childrenTransform && !m_childrenTransform->isIdentity(); } |
| 357 | |
| 358 | bool preserves3D() const { return m_preserves3D; } |
| 359 | virtual void setPreserves3D(bool b) { m_preserves3D = b; } |
| 360 | |
| 361 | bool masksToBounds() const { return m_masksToBounds; } |
| 362 | virtual void setMasksToBounds(bool b) { m_masksToBounds = b; } |
| 363 | |
| 364 | bool drawsContent() const { return m_drawsContent; } |
| 365 | virtual void setDrawsContent(bool b) { m_drawsContent = b; } |
| 366 | |
| 367 | bool contentsAreVisible() const { return m_contentsVisible; } |
| 368 | virtual void setContentsVisible(bool b) { m_contentsVisible = b; } |
| 369 | |
| 370 | bool userInteractionEnabled() const { return m_userInteractionEnabled; } |
| 371 | virtual void setUserInteractionEnabled(bool b) { m_userInteractionEnabled = b; } |
| 372 | |
| 373 | bool acceleratesDrawing() const { return m_acceleratesDrawing; } |
| 374 | virtual void setAcceleratesDrawing(bool b) { m_acceleratesDrawing = b; } |
| 375 | |
| 376 | bool usesDisplayListDrawing() const { return m_usesDisplayListDrawing; } |
| 377 | virtual void setUsesDisplayListDrawing(bool b) { m_usesDisplayListDrawing = b; } |
| 378 | |
| 379 | bool needsBackdrop() const { return !m_backdropFilters.isEmpty(); } |
| 380 | |
| 381 | // The color used to paint the layer background. Pass an invalid color to remove it. |
| 382 | // Note that this covers the entire layer. Use setContentsToSolidColor() if the color should |
| 383 | // only cover the contentsRect. |
| 384 | const Color& backgroundColor() const { return m_backgroundColor; } |
| 385 | WEBCORE_EXPORT virtual void setBackgroundColor(const Color&); |
| 386 | |
| 387 | // opaque means that we know the layer contents have no alpha |
| 388 | bool contentsOpaque() const { return m_contentsOpaque; } |
| 389 | virtual void setContentsOpaque(bool b) { m_contentsOpaque = b; } |
| 390 | |
| 391 | bool supportsSubpixelAntialiasedText() const { return m_supportsSubpixelAntialiasedText; } |
| 392 | virtual void setSupportsSubpixelAntialiasedText(bool b) { m_supportsSubpixelAntialiasedText = b; } |
| 393 | |
| 394 | bool backfaceVisibility() const { return m_backfaceVisibility; } |
| 395 | virtual void setBackfaceVisibility(bool b) { m_backfaceVisibility = b; } |
| 396 | |
| 397 | float opacity() const { return m_opacity; } |
| 398 | virtual void setOpacity(float opacity) { m_opacity = opacity; } |
| 399 | |
| 400 | const FilterOperations& filters() const { return m_filters; } |
| 401 | // Returns true if filter can be rendered by the compositor. |
| 402 | virtual bool setFilters(const FilterOperations& filters) { m_filters = filters; return true; } |
| 403 | |
| 404 | const FilterOperations& backdropFilters() const { return m_backdropFilters; } |
| 405 | virtual bool setBackdropFilters(const FilterOperations& filters) { m_backdropFilters = filters; return true; } |
| 406 | |
| 407 | virtual void setBackdropFiltersRect(const FloatRoundedRect& backdropFiltersRect) { m_backdropFiltersRect = backdropFiltersRect; } |
| 408 | const FloatRoundedRect& backdropFiltersRect() const { return m_backdropFiltersRect; } |
| 409 | |
| 410 | #if ENABLE(CSS_COMPOSITING) |
| 411 | BlendMode blendMode() const { return m_blendMode; } |
| 412 | virtual void setBlendMode(BlendMode blendMode) { m_blendMode = blendMode; } |
| 413 | #endif |
| 414 | |
| 415 | // Some GraphicsLayers paint only the foreground or the background content |
| 416 | GraphicsLayerPaintingPhase paintingPhase() const { return m_paintingPhase; } |
| 417 | void setPaintingPhase(GraphicsLayerPaintingPhase phase) { m_paintingPhase = phase; } |
| 418 | |
| 419 | enum ShouldClipToLayer { |
| 420 | DoNotClipToLayer, |
| 421 | ClipToLayer |
| 422 | }; |
| 423 | |
| 424 | virtual void setNeedsDisplay() = 0; |
| 425 | // mark the given rect (in layer coords) as needing dispay. Never goes deep. |
| 426 | virtual void setNeedsDisplayInRect(const FloatRect&, ShouldClipToLayer = ClipToLayer) = 0; |
| 427 | |
| 428 | virtual void setContentsNeedsDisplay() { }; |
| 429 | |
| 430 | // The tile phase is relative to the GraphicsLayer bounds. |
| 431 | virtual void setContentsTilePhase(const FloatSize& p) { m_contentsTilePhase = p; } |
| 432 | FloatSize contentsTilePhase() const { return m_contentsTilePhase; } |
| 433 | |
| 434 | virtual void setContentsTileSize(const FloatSize& s) { m_contentsTileSize = s; } |
| 435 | FloatSize contentsTileSize() const { return m_contentsTileSize; } |
| 436 | bool hasContentsTiling() const { return !m_contentsTileSize.isEmpty(); } |
| 437 | |
| 438 | // Set that the position/size of the contents (image or video). |
| 439 | FloatRect contentsRect() const { return m_contentsRect; } |
| 440 | virtual void setContentsRect(const FloatRect& r) { m_contentsRect = r; } |
| 441 | |
| 442 | // Set a rounded rect that will be used to clip the layer contents. |
| 443 | FloatRoundedRect contentsClippingRect() const { return m_contentsClippingRect; } |
| 444 | virtual void setContentsClippingRect(const FloatRoundedRect& roundedRect) { m_contentsClippingRect = roundedRect; } |
| 445 | |
| 446 | // Set a rounded rect that is used to clip this layer and its descendants (implies setting masksToBounds). |
| 447 | // Returns false if the platform can't support this rounded clip, and we should fall back to painting a mask. |
| 448 | FloatRoundedRect maskToBoundsRect() const { return m_masksToBoundsRect; }; |
| 449 | virtual bool setMasksToBoundsRect(const FloatRoundedRect& roundedRect) { m_masksToBoundsRect = roundedRect; return false; } |
| 450 | |
| 451 | Path shapeLayerPath() const; |
| 452 | virtual void setShapeLayerPath(const Path&); |
| 453 | |
| 454 | WindRule shapeLayerWindRule() const; |
| 455 | virtual void setShapeLayerWindRule(WindRule); |
| 456 | |
| 457 | const EventRegion& eventRegion() const { return m_eventRegion; } |
| 458 | virtual void setEventRegion(EventRegion&&); |
| 459 | |
| 460 | // Transitions are identified by a special animation name that cannot clash with a keyframe identifier. |
| 461 | static String animationNameForTransition(AnimatedPropertyID); |
| 462 | |
| 463 | // Return true if the animation is handled by the compositing system. If this returns |
| 464 | // false, the animation will be run by CSSAnimationController. |
| 465 | // These methods handle both transitions and keyframe animations. |
| 466 | virtual bool addAnimation(const KeyframeValueList&, const FloatSize& /*boxSize*/, const Animation*, const String& /*animationName*/, double /*timeOffset*/) { return false; } |
| 467 | virtual void pauseAnimation(const String& /*animationName*/, double /*timeOffset*/) { } |
| 468 | virtual void seekAnimation(const String& /*animationName*/, double /*timeOffset*/) { } |
| 469 | virtual void removeAnimation(const String& /*animationName*/) { } |
| 470 | |
| 471 | WEBCORE_EXPORT virtual void suspendAnimations(MonotonicTime); |
| 472 | WEBCORE_EXPORT virtual void resumeAnimations(); |
| 473 | |
| 474 | virtual Vector<std::pair<String, double>> acceleratedAnimationsForTesting() const { return { }; } |
| 475 | |
| 476 | // Layer contents |
| 477 | virtual void setContentsToImage(Image*) { } |
| 478 | virtual bool shouldDirectlyCompositeImage(Image*) const { return true; } |
| 479 | #if PLATFORM(IOS_FAMILY) |
| 480 | virtual PlatformLayer* contentsLayerForMedia() const { return 0; } |
| 481 | #endif |
| 482 | |
| 483 | enum class ContentsLayerPurpose : uint8_t { |
| 484 | None = 0, |
| 485 | Image, |
| 486 | Media, |
| 487 | Canvas, |
| 488 | BackgroundColor, |
| 489 | Plugin, |
| 490 | EmbeddedView |
| 491 | }; |
| 492 | |
| 493 | enum class ContentsLayerEmbeddedViewType : uint8_t { |
| 494 | None = 0, |
| 495 | EditableImage, |
| 496 | }; |
| 497 | |
| 498 | using EmbeddedViewID = uint64_t; |
| 499 | static EmbeddedViewID nextEmbeddedViewID(); |
| 500 | |
| 501 | // Pass an invalid color to remove the contents layer. |
| 502 | virtual void setContentsToSolidColor(const Color&) { } |
| 503 | virtual void setContentsToEmbeddedView(GraphicsLayer::ContentsLayerEmbeddedViewType, EmbeddedViewID) { } |
| 504 | virtual void setContentsToPlatformLayer(PlatformLayer*, ContentsLayerPurpose) { } |
| 505 | virtual bool usesContentsLayer() const { return false; } |
| 506 | |
| 507 | // Callback from the underlying graphics system to draw layer contents. |
| 508 | void paintGraphicsLayerContents(GraphicsContext&, const FloatRect& clip, GraphicsLayerPaintBehavior = GraphicsLayerPaintNormal); |
| 509 | |
| 510 | // For hosting this GraphicsLayer in a native layer hierarchy. |
| 511 | virtual PlatformLayer* platformLayer() const { return 0; } |
| 512 | |
| 513 | enum class CompositingCoordinatesOrientation : uint8_t { TopDown, BottomUp }; |
| 514 | |
| 515 | // Flippedness of the contents of this layer. Does not affect sublayer geometry. |
| 516 | virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation) { m_contentsOrientation = orientation; } |
| 517 | CompositingCoordinatesOrientation contentsOrientation() const { return m_contentsOrientation; } |
| 518 | |
| 519 | void dumpLayer(WTF::TextStream&, LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const; |
| 520 | |
| 521 | virtual void setShowDebugBorder(bool show) { m_showDebugBorder = show; } |
| 522 | bool isShowingDebugBorder() const { return m_showDebugBorder; } |
| 523 | |
| 524 | virtual void setShowRepaintCounter(bool show) { m_showRepaintCounter = show; } |
| 525 | bool isShowingRepaintCounter() const { return m_showRepaintCounter; } |
| 526 | |
| 527 | // FIXME: this is really a paint count. |
| 528 | int repaintCount() const { return m_repaintCount; } |
| 529 | int incrementRepaintCount() { return ++m_repaintCount; } |
| 530 | |
| 531 | virtual void setDebugBackgroundColor(const Color&) { } |
| 532 | virtual void setDebugBorder(const Color&, float /*borderWidth*/) { } |
| 533 | |
| 534 | enum class CustomAppearance : uint8_t { |
| 535 | None, |
| 536 | ScrollingOverhang, |
| 537 | ScrollingShadow, |
| 538 | LightBackdrop, |
| 539 | DarkBackdrop |
| 540 | }; |
| 541 | virtual void setCustomAppearance(CustomAppearance customAppearance) { m_customAppearance = customAppearance; } |
| 542 | CustomAppearance customAppearance() const { return m_customAppearance; } |
| 543 | |
| 544 | // z-position is the z-equivalent of position(). It's only used for debugging purposes. |
| 545 | virtual float zPosition() const { return m_zPosition; } |
| 546 | WEBCORE_EXPORT virtual void setZPosition(float); |
| 547 | |
| 548 | WEBCORE_EXPORT virtual void distributeOpacity(float); |
| 549 | WEBCORE_EXPORT virtual float accumulatedOpacity() const; |
| 550 | |
| 551 | virtual FloatSize pixelAlignmentOffset() const { return FloatSize(); } |
| 552 | |
| 553 | virtual void setAppliesPageScale(bool appliesScale = true) { m_appliesPageScale = appliesScale; } |
| 554 | virtual bool appliesPageScale() const { return m_appliesPageScale; } |
| 555 | |
| 556 | float pageScaleFactor() const { return client().pageScaleFactor(); } |
| 557 | float deviceScaleFactor() const { return client().deviceScaleFactor(); } |
| 558 | |
| 559 | // Whether this layer is viewport constrained, implying that it's moved around externally from GraphicsLayer (e.g. by the scrolling tree). |
| 560 | virtual void setIsViewportConstrained(bool) { } |
| 561 | virtual bool isViewportConstrained() const { return false; } |
| 562 | |
| 563 | virtual void deviceOrPageScaleFactorChanged() { } |
| 564 | WEBCORE_EXPORT void noteDeviceOrPageScaleFactorChangedIncludingDescendants(); |
| 565 | |
| 566 | void setIsInWindow(bool); |
| 567 | |
| 568 | // Some compositing systems may do internal batching to synchronize compositing updates |
| 569 | // with updates drawn into the window. These methods flush internal batched state on this layer |
| 570 | // and descendant layers, and this layer only. |
| 571 | virtual void flushCompositingState(const FloatRect& /* clipRect */) { } |
| 572 | virtual void flushCompositingStateForThisLayerOnly() { } |
| 573 | |
| 574 | // If the exposed rect of this layer changes, returns true if this or descendant layers need a flush, |
| 575 | // for example to allocate new tiles. |
| 576 | virtual bool visibleRectChangeRequiresFlush(const FloatRect& /* clipRect */) const { return false; } |
| 577 | |
| 578 | // Return a string with a human readable form of the layer tree, If debug is true |
| 579 | // pointers for the layers and timing data will be included in the returned string. |
| 580 | WEBCORE_EXPORT String layerTreeAsText(LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const; |
| 581 | |
| 582 | // For testing. |
| 583 | virtual String displayListAsText(DisplayList::AsTextFlags) const { return String(); } |
| 584 | |
| 585 | virtual void setIsTrackingDisplayListReplay(bool isTracking) { m_isTrackingDisplayListReplay = isTracking; } |
| 586 | virtual bool isTrackingDisplayListReplay() const { return m_isTrackingDisplayListReplay; } |
| 587 | virtual String replayDisplayListAsText(DisplayList::AsTextFlags) const { return String(); } |
| 588 | |
| 589 | // Return an estimate of the backing store memory cost (in bytes). May be incorrect for tiled layers. |
| 590 | WEBCORE_EXPORT virtual double backingStoreMemoryEstimate() const; |
| 591 | |
| 592 | virtual bool backingStoreAttached() const { return true; } |
| 593 | virtual bool backingStoreAttachedForTesting() const { return backingStoreAttached(); } |
| 594 | |
| 595 | void setCanDetachBackingStore(bool b) { m_canDetachBackingStore = b; } |
| 596 | bool canDetachBackingStore() const { return m_canDetachBackingStore; } |
| 597 | |
| 598 | virtual TiledBacking* tiledBacking() const { return 0; } |
| 599 | |
| 600 | void resetTrackedRepaints(); |
| 601 | void addRepaintRect(const FloatRect&); |
| 602 | |
| 603 | static bool supportsBackgroundColorContent(); |
| 604 | static bool supportsLayerType(Type); |
| 605 | static bool supportsContentsTiling(); |
| 606 | static bool supportsSubpixelAntialiasedLayerText(); |
| 607 | |
| 608 | void updateDebugIndicators(); |
| 609 | |
| 610 | virtual bool canThrottleLayerFlush() const { return false; } |
| 611 | |
| 612 | virtual bool isGraphicsLayerCA() const { return false; } |
| 613 | virtual bool isGraphicsLayerCARemote() const { return false; } |
| 614 | virtual bool isGraphicsLayerTextureMapper() const { return false; } |
| 615 | virtual bool isCoordinatedGraphicsLayer() const { return false; } |
| 616 | |
| 617 | const Optional<FloatRect>& animationExtent() const { return m_animationExtent; } |
| 618 | void setAnimationExtent(Optional<FloatRect> animationExtent) { m_animationExtent = animationExtent; } |
| 619 | |
| 620 | static void traverse(GraphicsLayer&, const WTF::Function<void (GraphicsLayer&)>&); |
| 621 | |
| 622 | protected: |
| 623 | WEBCORE_EXPORT explicit GraphicsLayer(Type, GraphicsLayerClient&); |
| 624 | |
| 625 | // Should be called from derived class destructors. Should call willBeDestroyed() on super. |
| 626 | WEBCORE_EXPORT virtual void willBeDestroyed(); |
| 627 | bool beingDestroyed() const { return m_beingDestroyed; } |
| 628 | |
| 629 | // This method is used by platform GraphicsLayer classes to clear the filters |
| 630 | // when compositing is not done in hardware. It is not virtual, so the caller |
| 631 | // needs to notifiy the change to the platform layer as needed. |
| 632 | void clearFilters() { m_filters.clear(); } |
| 633 | void clearBackdropFilters() { m_backdropFilters.clear(); } |
| 634 | |
| 635 | // Given a KeyframeValueList containing filterOperations, return true if the operations are valid. |
| 636 | static int validateFilterOperations(const KeyframeValueList&); |
| 637 | |
| 638 | // Given a list of TransformAnimationValues, see if all the operations for each keyframe match. If so |
| 639 | // return the index of the KeyframeValueList entry that has that list of operations (it may not be |
| 640 | // the first entry because some keyframes might have an empty transform and those match any list). |
| 641 | // If the lists don't match return -1. On return, if hasBigRotation is true, functions contain |
| 642 | // rotations of >= 180 degrees |
| 643 | static int validateTransformOperations(const KeyframeValueList&, bool& hasBigRotation); |
| 644 | |
| 645 | virtual bool shouldRepaintOnSizeChange() const { return drawsContent(); } |
| 646 | |
| 647 | virtual void setOpacityInternal(float) { } |
| 648 | |
| 649 | // The layer being replicated. |
| 650 | GraphicsLayer* replicatedLayer() const { return m_replicatedLayer; } |
| 651 | virtual void setReplicatedLayer(GraphicsLayer* layer) { m_replicatedLayer = layer; } |
| 652 | |
| 653 | void dumpProperties(WTF::TextStream&, LayerTreeAsTextBehavior) const; |
| 654 | virtual void dumpAdditionalProperties(WTF::TextStream&, LayerTreeAsTextBehavior) const { } |
| 655 | |
| 656 | WEBCORE_EXPORT virtual void getDebugBorderInfo(Color&, float& width) const; |
| 657 | |
| 658 | GraphicsLayerClient* m_client; // Always non-null. |
| 659 | String m_name; |
| 660 | |
| 661 | // Offset from the owning renderer |
| 662 | FloatSize m_offsetFromRenderer; |
| 663 | |
| 664 | // Scroll offset of the content layer inside its scrolling parent layer. |
| 665 | ScrollOffset m_scrollOffset; |
| 666 | |
| 667 | // Position is relative to the parent GraphicsLayer |
| 668 | FloatPoint m_position; |
| 669 | |
| 670 | // If set, overrides m_position. Only used for coverage computation. |
| 671 | Optional<FloatPoint> m_approximatePosition; |
| 672 | |
| 673 | FloatPoint3D m_anchorPoint { 0.5f, 0.5f, 0 }; |
| 674 | FloatSize m_size; |
| 675 | FloatPoint m_boundsOrigin; |
| 676 | |
| 677 | std::unique_ptr<TransformationMatrix> m_transform; |
| 678 | std::unique_ptr<TransformationMatrix> m_childrenTransform; |
| 679 | |
| 680 | Color m_backgroundColor; |
| 681 | float m_opacity { 1 }; |
| 682 | float m_zPosition { 0 }; |
| 683 | |
| 684 | FilterOperations m_filters; |
| 685 | FilterOperations m_backdropFilters; |
| 686 | |
| 687 | #if ENABLE(CSS_COMPOSITING) |
| 688 | BlendMode m_blendMode { BlendMode::Normal }; |
| 689 | #endif |
| 690 | |
| 691 | const Type m_type; |
| 692 | CustomAppearance m_customAppearance { CustomAppearance::None }; |
| 693 | GraphicsLayerPaintingPhase m_paintingPhase { GraphicsLayerPaintAllWithOverflowClip }; |
| 694 | CompositingCoordinatesOrientation m_contentsOrientation { CompositingCoordinatesOrientation::TopDown }; // affects orientation of layer contents |
| 695 | |
| 696 | bool m_beingDestroyed : 1; |
| 697 | bool m_contentsOpaque : 1; |
| 698 | bool m_supportsSubpixelAntialiasedText : 1; |
| 699 | bool m_preserves3D: 1; |
| 700 | bool m_backfaceVisibility : 1; |
| 701 | bool m_masksToBounds : 1; |
| 702 | bool m_drawsContent : 1; |
| 703 | bool m_contentsVisible : 1; |
| 704 | bool m_acceleratesDrawing : 1; |
| 705 | bool m_usesDisplayListDrawing : 1; |
| 706 | bool m_appliesPageScale : 1; // Set for the layer which has the page scale applied to it. |
| 707 | bool m_showDebugBorder : 1; |
| 708 | bool m_showRepaintCounter : 1; |
| 709 | bool m_isMaskLayer : 1; |
| 710 | bool m_isTrackingDisplayListReplay : 1; |
| 711 | bool m_userInteractionEnabled : 1; |
| 712 | bool m_canDetachBackingStore : 1; |
| 713 | |
| 714 | int m_repaintCount { 0 }; |
| 715 | |
| 716 | Vector<Ref<GraphicsLayer>> m_children; |
| 717 | GraphicsLayer* m_parent { nullptr }; |
| 718 | |
| 719 | RefPtr<GraphicsLayer> m_maskLayer { nullptr }; // Reference to mask layer. |
| 720 | |
| 721 | RefPtr<GraphicsLayer> m_replicaLayer { nullptr }; // A layer that replicates this layer. We only allow one, for now. |
| 722 | // The replica is not parented; this is the primary reference to it. |
| 723 | GraphicsLayer* m_replicatedLayer { nullptr }; // For a replica layer, a reference to the original layer. |
| 724 | FloatPoint m_replicatedLayerPosition; // For a replica layer, the position of the replica. |
| 725 | |
| 726 | FloatRect m_contentsRect; |
| 727 | FloatRoundedRect m_contentsClippingRect; |
| 728 | FloatRoundedRect m_masksToBoundsRect; |
| 729 | FloatSize m_contentsTilePhase; |
| 730 | FloatSize m_contentsTileSize; |
| 731 | FloatRoundedRect m_backdropFiltersRect; |
| 732 | Optional<FloatRect> m_animationExtent; |
| 733 | |
| 734 | EventRegion m_eventRegion; |
| 735 | #if USE(CA) |
| 736 | WindRule m_shapeLayerWindRule { WindRule::NonZero }; |
| 737 | Path m_shapeLayerPath; |
| 738 | #endif |
| 739 | }; |
| 740 | |
| 741 | WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const Vector<GraphicsLayer::PlatformLayerID>&); |
| 742 | WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const GraphicsLayer::CustomAppearance&); |
| 743 | |
| 744 | } // namespace WebCore |
| 745 | |
| 746 | #define SPECIALIZE_TYPE_TRAITS_GRAPHICSLAYER(ToValueTypeName, predicate) \ |
| 747 | SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \ |
| 748 | static bool isType(const WebCore::GraphicsLayer& layer) { return layer.predicate; } \ |
| 749 | SPECIALIZE_TYPE_TRAITS_END() |
| 750 | |
| 751 | #if ENABLE(TREE_DEBUGGING) |
| 752 | // Outside the WebCore namespace for ease of invocation from the debugger. |
| 753 | void showGraphicsLayerTree(const WebCore::GraphicsLayer* layer); |
| 754 | #endif |
| 755 | |