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 | ScrolledContents, |
244 | Shape |
245 | }; |
246 | |
247 | WEBCORE_EXPORT static Ref<GraphicsLayer> create(GraphicsLayerFactory*, GraphicsLayerClient&, Type = Type::Normal); |
248 | |
249 | WEBCORE_EXPORT virtual ~GraphicsLayer(); |
250 | |
251 | // Unparent, clear the client, and clear the RefPtr. |
252 | WEBCORE_EXPORT static void unparentAndClear(RefPtr<GraphicsLayer>&); |
253 | // Clear the client, and clear the RefPtr, but leave parented. |
254 | WEBCORE_EXPORT static void clear(RefPtr<GraphicsLayer>&); |
255 | |
256 | WEBCORE_EXPORT void clearClient(); |
257 | WEBCORE_EXPORT void setClient(GraphicsLayerClient&); |
258 | |
259 | Type type() const { return m_type; } |
260 | |
261 | virtual void initialize(Type) { } |
262 | |
263 | using PlatformLayerID = uint64_t; |
264 | virtual PlatformLayerID primaryLayerID() const { return 0; } |
265 | |
266 | GraphicsLayerClient& client() const { return *m_client; } |
267 | |
268 | // Layer name. Only used to identify layers in debug output |
269 | const String& name() const { return m_name; } |
270 | virtual void setName(const String& name) { m_name = name; } |
271 | |
272 | GraphicsLayer* parent() const { return m_parent; }; |
273 | void setParent(GraphicsLayer*); // Internal use only. |
274 | |
275 | // Returns true if the layer has the given layer as an ancestor (excluding self). |
276 | bool hasAncestor(GraphicsLayer*) const; |
277 | |
278 | const Vector<Ref<GraphicsLayer>>& children() const { return m_children; } |
279 | Vector<Ref<GraphicsLayer>>& children() { return m_children; } |
280 | |
281 | // Returns true if the child list changed. |
282 | WEBCORE_EXPORT virtual bool setChildren(Vector<Ref<GraphicsLayer>>&&); |
283 | |
284 | // Add child layers. If the child is already parented, it will be removed from its old parent. |
285 | WEBCORE_EXPORT virtual void addChild(Ref<GraphicsLayer>&&); |
286 | WEBCORE_EXPORT virtual void addChildAtIndex(Ref<GraphicsLayer>&&, int index); |
287 | WEBCORE_EXPORT virtual void addChildAbove(Ref<GraphicsLayer>&&, GraphicsLayer* sibling); |
288 | WEBCORE_EXPORT virtual void addChildBelow(Ref<GraphicsLayer>&&, GraphicsLayer* sibling); |
289 | WEBCORE_EXPORT virtual bool replaceChild(GraphicsLayer* oldChild, Ref<GraphicsLayer>&& newChild); |
290 | |
291 | WEBCORE_EXPORT void removeAllChildren(); |
292 | WEBCORE_EXPORT virtual void removeFromParent(); |
293 | |
294 | // The parent() of a maskLayer is set to the layer being masked. |
295 | GraphicsLayer* maskLayer() const { return m_maskLayer.get(); } |
296 | virtual void setMaskLayer(RefPtr<GraphicsLayer>&&); |
297 | |
298 | void setIsMaskLayer(bool isMask) { m_isMaskLayer = isMask; } |
299 | bool isMaskLayer() const { return m_isMaskLayer; } |
300 | |
301 | // The given layer will replicate this layer and its children; the replica renders behind this layer. |
302 | WEBCORE_EXPORT virtual void setReplicatedByLayer(RefPtr<GraphicsLayer>&&); |
303 | // Whether this layer is being replicated by another layer. |
304 | bool isReplicated() const { return m_replicaLayer; } |
305 | // The layer that replicates this layer (if any). |
306 | GraphicsLayer* replicaLayer() const { return m_replicaLayer.get(); } |
307 | |
308 | const FloatPoint& replicatedLayerPosition() const { return m_replicatedLayerPosition; } |
309 | void setReplicatedLayerPosition(const FloatPoint& p) { m_replicatedLayerPosition = p; } |
310 | |
311 | enum ShouldSetNeedsDisplay { |
312 | DontSetNeedsDisplay, |
313 | SetNeedsDisplay |
314 | }; |
315 | |
316 | // Offset is origin of the renderer minus origin of the graphics layer. |
317 | FloatSize offsetFromRenderer() const { return m_offsetFromRenderer; } |
318 | void setOffsetFromRenderer(const FloatSize&, ShouldSetNeedsDisplay = SetNeedsDisplay); |
319 | |
320 | // Scroll offset of the content layer inside its scrolling parent layer. |
321 | ScrollOffset scrollOffset() const { return m_scrollOffset; } |
322 | void setScrollOffset(const ScrollOffset&, ShouldSetNeedsDisplay = SetNeedsDisplay); |
323 | |
324 | // The position of the layer (the location of its top-left corner in its parent) |
325 | const FloatPoint& position() const { return m_position; } |
326 | virtual void setPosition(const FloatPoint& p) { m_approximatePosition = WTF::nullopt; m_position = p; } |
327 | |
328 | // approximatePosition, if set, overrides position() and is used during coverage rect computation. |
329 | FloatPoint approximatePosition() const { return m_approximatePosition ? m_approximatePosition.value() : m_position; } |
330 | virtual void setApproximatePosition(const FloatPoint& p) { m_approximatePosition = p; } |
331 | |
332 | // For platforms that move underlying platform layers on a different thread for scrolling; just update the GraphicsLayer state. |
333 | virtual void syncPosition(const FloatPoint& p) { m_position = p; } |
334 | |
335 | // Anchor point: (0, 0) is top left, (1, 1) is bottom right. The anchor point |
336 | // affects the origin of the transforms. |
337 | const FloatPoint3D& anchorPoint() const { return m_anchorPoint; } |
338 | virtual void setAnchorPoint(const FloatPoint3D& p) { m_anchorPoint = p; } |
339 | |
340 | // The size of the layer. |
341 | const FloatSize& size() const { return m_size; } |
342 | WEBCORE_EXPORT virtual void setSize(const FloatSize&); |
343 | |
344 | // The boundOrigin affects the offset at which content is rendered, and sublayers are positioned. |
345 | const FloatPoint& boundsOrigin() const { return m_boundsOrigin; } |
346 | virtual void setBoundsOrigin(const FloatPoint& origin) { m_boundsOrigin = origin; } |
347 | |
348 | // For platforms that move underlying platform layers on a different thread for scrolling; just update the GraphicsLayer state. |
349 | virtual void syncBoundsOrigin(const FloatPoint& origin) { m_boundsOrigin = origin; } |
350 | |
351 | const TransformationMatrix& transform() const; |
352 | virtual void setTransform(const TransformationMatrix&); |
353 | bool hasNonIdentityTransform() const { return m_transform && !m_transform->isIdentity(); } |
354 | |
355 | const TransformationMatrix& childrenTransform() const; |
356 | virtual void setChildrenTransform(const TransformationMatrix&); |
357 | bool hasNonIdentityChildrenTransform() const { return m_childrenTransform && !m_childrenTransform->isIdentity(); } |
358 | |
359 | bool preserves3D() const { return m_preserves3D; } |
360 | virtual void setPreserves3D(bool b) { m_preserves3D = b; } |
361 | |
362 | bool masksToBounds() const { return m_masksToBounds; } |
363 | virtual void setMasksToBounds(bool b) { m_masksToBounds = b; } |
364 | |
365 | bool drawsContent() const { return m_drawsContent; } |
366 | virtual void setDrawsContent(bool b) { m_drawsContent = b; } |
367 | |
368 | bool contentsAreVisible() const { return m_contentsVisible; } |
369 | virtual void setContentsVisible(bool b) { m_contentsVisible = b; } |
370 | |
371 | bool userInteractionEnabled() const { return m_userInteractionEnabled; } |
372 | virtual void setUserInteractionEnabled(bool b) { m_userInteractionEnabled = b; } |
373 | |
374 | bool acceleratesDrawing() const { return m_acceleratesDrawing; } |
375 | virtual void setAcceleratesDrawing(bool b) { m_acceleratesDrawing = b; } |
376 | |
377 | bool usesDisplayListDrawing() const { return m_usesDisplayListDrawing; } |
378 | virtual void setUsesDisplayListDrawing(bool b) { m_usesDisplayListDrawing = b; } |
379 | |
380 | bool needsBackdrop() const { return !m_backdropFilters.isEmpty(); } |
381 | |
382 | // The color used to paint the layer background. Pass an invalid color to remove it. |
383 | // Note that this covers the entire layer. Use setContentsToSolidColor() if the color should |
384 | // only cover the contentsRect. |
385 | const Color& backgroundColor() const { return m_backgroundColor; } |
386 | WEBCORE_EXPORT virtual void setBackgroundColor(const Color&); |
387 | |
388 | // opaque means that we know the layer contents have no alpha |
389 | bool contentsOpaque() const { return m_contentsOpaque; } |
390 | virtual void setContentsOpaque(bool b) { m_contentsOpaque = b; } |
391 | |
392 | bool supportsSubpixelAntialiasedText() const { return m_supportsSubpixelAntialiasedText; } |
393 | virtual void setSupportsSubpixelAntialiasedText(bool b) { m_supportsSubpixelAntialiasedText = b; } |
394 | |
395 | bool backfaceVisibility() const { return m_backfaceVisibility; } |
396 | virtual void setBackfaceVisibility(bool b) { m_backfaceVisibility = b; } |
397 | |
398 | float opacity() const { return m_opacity; } |
399 | virtual void setOpacity(float opacity) { m_opacity = opacity; } |
400 | |
401 | const FilterOperations& filters() const { return m_filters; } |
402 | // Returns true if filter can be rendered by the compositor. |
403 | virtual bool setFilters(const FilterOperations& filters) { m_filters = filters; return true; } |
404 | |
405 | const FilterOperations& backdropFilters() const { return m_backdropFilters; } |
406 | virtual bool setBackdropFilters(const FilterOperations& filters) { m_backdropFilters = filters; return true; } |
407 | |
408 | virtual void setBackdropFiltersRect(const FloatRoundedRect& backdropFiltersRect) { m_backdropFiltersRect = backdropFiltersRect; } |
409 | const FloatRoundedRect& backdropFiltersRect() const { return m_backdropFiltersRect; } |
410 | |
411 | #if ENABLE(CSS_COMPOSITING) |
412 | BlendMode blendMode() const { return m_blendMode; } |
413 | virtual void setBlendMode(BlendMode blendMode) { m_blendMode = blendMode; } |
414 | #endif |
415 | |
416 | // Some GraphicsLayers paint only the foreground or the background content |
417 | OptionSet<GraphicsLayerPaintingPhase> paintingPhase() const { return m_paintingPhase; } |
418 | void setPaintingPhase(OptionSet<GraphicsLayerPaintingPhase>); |
419 | |
420 | enum ShouldClipToLayer { |
421 | DoNotClipToLayer, |
422 | ClipToLayer |
423 | }; |
424 | |
425 | virtual void setNeedsDisplay() = 0; |
426 | // mark the given rect (in layer coords) as needing dispay. Never goes deep. |
427 | virtual void setNeedsDisplayInRect(const FloatRect&, ShouldClipToLayer = ClipToLayer) = 0; |
428 | |
429 | virtual void setContentsNeedsDisplay() { }; |
430 | |
431 | // The tile phase is relative to the GraphicsLayer bounds. |
432 | virtual void setContentsTilePhase(const FloatSize& p) { m_contentsTilePhase = p; } |
433 | FloatSize contentsTilePhase() const { return m_contentsTilePhase; } |
434 | |
435 | virtual void setContentsTileSize(const FloatSize& s) { m_contentsTileSize = s; } |
436 | FloatSize contentsTileSize() const { return m_contentsTileSize; } |
437 | bool hasContentsTiling() const { return !m_contentsTileSize.isEmpty(); } |
438 | |
439 | // Set that the position/size of the contents (image or video). |
440 | FloatRect contentsRect() const { return m_contentsRect; } |
441 | virtual void setContentsRect(const FloatRect& r) { m_contentsRect = r; } |
442 | |
443 | // Set a rounded rect that will be used to clip the layer contents. |
444 | FloatRoundedRect contentsClippingRect() const { return m_contentsClippingRect; } |
445 | virtual void setContentsClippingRect(const FloatRoundedRect& roundedRect) { m_contentsClippingRect = roundedRect; } |
446 | |
447 | // Set a rounded rect that is used to clip this layer and its descendants (implies setting masksToBounds). |
448 | // Returns false if the platform can't support this rounded clip, and we should fall back to painting a mask. |
449 | FloatRoundedRect maskToBoundsRect() const { return m_masksToBoundsRect; }; |
450 | virtual bool setMasksToBoundsRect(const FloatRoundedRect& roundedRect) { m_masksToBoundsRect = roundedRect; return false; } |
451 | |
452 | Path shapeLayerPath() const; |
453 | virtual void setShapeLayerPath(const Path&); |
454 | |
455 | WindRule shapeLayerWindRule() const; |
456 | virtual void setShapeLayerWindRule(WindRule); |
457 | |
458 | const EventRegion& eventRegion() const { return m_eventRegion; } |
459 | virtual void setEventRegion(EventRegion&&); |
460 | |
461 | // Transitions are identified by a special animation name that cannot clash with a keyframe identifier. |
462 | static String animationNameForTransition(AnimatedPropertyID); |
463 | |
464 | // Return true if the animation is handled by the compositing system. If this returns |
465 | // false, the animation will be run by CSSAnimationController. |
466 | // These methods handle both transitions and keyframe animations. |
467 | virtual bool addAnimation(const KeyframeValueList&, const FloatSize& /*boxSize*/, const Animation*, const String& /*animationName*/, double /*timeOffset*/) { return false; } |
468 | virtual void pauseAnimation(const String& /*animationName*/, double /*timeOffset*/) { } |
469 | virtual void seekAnimation(const String& /*animationName*/, double /*timeOffset*/) { } |
470 | virtual void removeAnimation(const String& /*animationName*/) { } |
471 | |
472 | WEBCORE_EXPORT virtual void suspendAnimations(MonotonicTime); |
473 | WEBCORE_EXPORT virtual void resumeAnimations(); |
474 | |
475 | virtual Vector<std::pair<String, double>> acceleratedAnimationsForTesting() const { return { }; } |
476 | |
477 | // Layer contents |
478 | virtual void setContentsToImage(Image*) { } |
479 | virtual bool shouldDirectlyCompositeImage(Image*) const { return true; } |
480 | #if PLATFORM(IOS_FAMILY) |
481 | virtual PlatformLayer* contentsLayerForMedia() const { return 0; } |
482 | #endif |
483 | |
484 | enum class ContentsLayerPurpose : uint8_t { |
485 | None = 0, |
486 | Image, |
487 | Media, |
488 | Canvas, |
489 | BackgroundColor, |
490 | Plugin, |
491 | EmbeddedView |
492 | }; |
493 | |
494 | enum class ContentsLayerEmbeddedViewType : uint8_t { |
495 | None = 0, |
496 | EditableImage, |
497 | }; |
498 | |
499 | using EmbeddedViewID = uint64_t; |
500 | static EmbeddedViewID nextEmbeddedViewID(); |
501 | |
502 | // Pass an invalid color to remove the contents layer. |
503 | virtual void setContentsToSolidColor(const Color&) { } |
504 | virtual void setContentsToEmbeddedView(GraphicsLayer::ContentsLayerEmbeddedViewType, EmbeddedViewID) { } |
505 | virtual void setContentsToPlatformLayer(PlatformLayer*, ContentsLayerPurpose) { } |
506 | virtual bool usesContentsLayer() const { return false; } |
507 | |
508 | // Callback from the underlying graphics system to draw layer contents. |
509 | void paintGraphicsLayerContents(GraphicsContext&, const FloatRect& clip, GraphicsLayerPaintBehavior = GraphicsLayerPaintNormal); |
510 | |
511 | // For hosting this GraphicsLayer in a native layer hierarchy. |
512 | virtual PlatformLayer* platformLayer() const { return 0; } |
513 | |
514 | enum class CompositingCoordinatesOrientation : uint8_t { TopDown, BottomUp }; |
515 | |
516 | // Flippedness of the contents of this layer. Does not affect sublayer geometry. |
517 | virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation) { m_contentsOrientation = orientation; } |
518 | CompositingCoordinatesOrientation contentsOrientation() const { return m_contentsOrientation; } |
519 | |
520 | void dumpLayer(WTF::TextStream&, LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const; |
521 | |
522 | virtual void setShowDebugBorder(bool show) { m_showDebugBorder = show; } |
523 | bool isShowingDebugBorder() const { return m_showDebugBorder; } |
524 | |
525 | virtual void setShowRepaintCounter(bool show) { m_showRepaintCounter = show; } |
526 | bool isShowingRepaintCounter() const { return m_showRepaintCounter; } |
527 | |
528 | // FIXME: this is really a paint count. |
529 | int repaintCount() const { return m_repaintCount; } |
530 | int incrementRepaintCount() { return ++m_repaintCount; } |
531 | |
532 | virtual void setDebugBackgroundColor(const Color&) { } |
533 | virtual void setDebugBorder(const Color&, float /*borderWidth*/) { } |
534 | |
535 | enum class CustomAppearance : uint8_t { |
536 | None, |
537 | ScrollingOverhang, |
538 | ScrollingShadow, |
539 | LightBackdrop, |
540 | DarkBackdrop |
541 | }; |
542 | virtual void setCustomAppearance(CustomAppearance customAppearance) { m_customAppearance = customAppearance; } |
543 | CustomAppearance customAppearance() const { return m_customAppearance; } |
544 | |
545 | // z-position is the z-equivalent of position(). It's only used for debugging purposes. |
546 | virtual float zPosition() const { return m_zPosition; } |
547 | WEBCORE_EXPORT virtual void setZPosition(float); |
548 | |
549 | WEBCORE_EXPORT virtual void distributeOpacity(float); |
550 | WEBCORE_EXPORT virtual float accumulatedOpacity() const; |
551 | |
552 | virtual FloatSize pixelAlignmentOffset() const { return FloatSize(); } |
553 | |
554 | virtual void setAppliesPageScale(bool appliesScale = true) { m_appliesPageScale = appliesScale; } |
555 | virtual bool appliesPageScale() const { return m_appliesPageScale; } |
556 | |
557 | float pageScaleFactor() const { return client().pageScaleFactor(); } |
558 | float deviceScaleFactor() const { return client().deviceScaleFactor(); } |
559 | |
560 | // Whether this layer is viewport constrained, implying that it's moved around externally from GraphicsLayer (e.g. by the scrolling tree). |
561 | virtual void setIsViewportConstrained(bool) { } |
562 | virtual bool isViewportConstrained() const { return false; } |
563 | |
564 | virtual void deviceOrPageScaleFactorChanged() { } |
565 | WEBCORE_EXPORT void noteDeviceOrPageScaleFactorChangedIncludingDescendants(); |
566 | |
567 | void setIsInWindow(bool); |
568 | |
569 | // Some compositing systems may do internal batching to synchronize compositing updates |
570 | // with updates drawn into the window. These methods flush internal batched state on this layer |
571 | // and descendant layers, and this layer only. |
572 | virtual void flushCompositingState(const FloatRect& /* clipRect */) { } |
573 | virtual void flushCompositingStateForThisLayerOnly() { } |
574 | |
575 | // If the exposed rect of this layer changes, returns true if this or descendant layers need a flush, |
576 | // for example to allocate new tiles. |
577 | virtual bool visibleRectChangeRequiresFlush(const FloatRect& /* clipRect */) const { return false; } |
578 | |
579 | static FloatRect adjustCoverageRectForMovement(const FloatRect& coverageRect, const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect); |
580 | |
581 | // Return a string with a human readable form of the layer tree, If debug is true |
582 | // pointers for the layers and timing data will be included in the returned string. |
583 | WEBCORE_EXPORT String layerTreeAsText(LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const; |
584 | |
585 | // For testing. |
586 | virtual String displayListAsText(DisplayList::AsTextFlags) const { return String(); } |
587 | |
588 | virtual void setIsTrackingDisplayListReplay(bool isTracking) { m_isTrackingDisplayListReplay = isTracking; } |
589 | virtual bool isTrackingDisplayListReplay() const { return m_isTrackingDisplayListReplay; } |
590 | virtual String replayDisplayListAsText(DisplayList::AsTextFlags) const { return String(); } |
591 | |
592 | // Return an estimate of the backing store memory cost (in bytes). May be incorrect for tiled layers. |
593 | WEBCORE_EXPORT virtual double backingStoreMemoryEstimate() const; |
594 | |
595 | virtual bool backingStoreAttached() const { return true; } |
596 | virtual bool backingStoreAttachedForTesting() const { return backingStoreAttached(); } |
597 | |
598 | void setCanDetachBackingStore(bool b) { m_canDetachBackingStore = b; } |
599 | bool canDetachBackingStore() const { return m_canDetachBackingStore; } |
600 | |
601 | virtual TiledBacking* tiledBacking() const { return 0; } |
602 | |
603 | void resetTrackedRepaints(); |
604 | void addRepaintRect(const FloatRect&); |
605 | |
606 | static bool supportsBackgroundColorContent(); |
607 | static bool supportsLayerType(Type); |
608 | static bool supportsContentsTiling(); |
609 | static bool supportsSubpixelAntialiasedLayerText(); |
610 | |
611 | void updateDebugIndicators(); |
612 | |
613 | virtual bool canThrottleLayerFlush() const { return false; } |
614 | |
615 | virtual bool isGraphicsLayerCA() const { return false; } |
616 | virtual bool isGraphicsLayerCARemote() const { return false; } |
617 | virtual bool isGraphicsLayerTextureMapper() const { return false; } |
618 | virtual bool isCoordinatedGraphicsLayer() const { return false; } |
619 | |
620 | const Optional<FloatRect>& animationExtent() const { return m_animationExtent; } |
621 | void setAnimationExtent(Optional<FloatRect> animationExtent) { m_animationExtent = animationExtent; } |
622 | |
623 | static void traverse(GraphicsLayer&, const WTF::Function<void (GraphicsLayer&)>&); |
624 | |
625 | protected: |
626 | WEBCORE_EXPORT explicit GraphicsLayer(Type, GraphicsLayerClient&); |
627 | |
628 | // Should be called from derived class destructors. Should call willBeDestroyed() on super. |
629 | WEBCORE_EXPORT virtual void willBeDestroyed(); |
630 | bool beingDestroyed() const { return m_beingDestroyed; } |
631 | |
632 | // This method is used by platform GraphicsLayer classes to clear the filters |
633 | // when compositing is not done in hardware. It is not virtual, so the caller |
634 | // needs to notifiy the change to the platform layer as needed. |
635 | void clearFilters() { m_filters.clear(); } |
636 | void clearBackdropFilters() { m_backdropFilters.clear(); } |
637 | |
638 | // Given a KeyframeValueList containing filterOperations, return true if the operations are valid. |
639 | static int validateFilterOperations(const KeyframeValueList&); |
640 | |
641 | // Given a list of TransformAnimationValues, see if all the operations for each keyframe match. If so |
642 | // return the index of the KeyframeValueList entry that has that list of operations (it may not be |
643 | // the first entry because some keyframes might have an empty transform and those match any list). |
644 | // If the lists don't match return -1. On return, if hasBigRotation is true, functions contain |
645 | // rotations of >= 180 degrees |
646 | static int validateTransformOperations(const KeyframeValueList&, bool& hasBigRotation); |
647 | |
648 | virtual bool shouldRepaintOnSizeChange() const { return drawsContent(); } |
649 | |
650 | virtual void setOpacityInternal(float) { } |
651 | |
652 | // The layer being replicated. |
653 | GraphicsLayer* replicatedLayer() const { return m_replicatedLayer; } |
654 | virtual void setReplicatedLayer(GraphicsLayer* layer) { m_replicatedLayer = layer; } |
655 | |
656 | void dumpProperties(WTF::TextStream&, LayerTreeAsTextBehavior) const; |
657 | virtual void dumpAdditionalProperties(WTF::TextStream&, LayerTreeAsTextBehavior) const { } |
658 | |
659 | WEBCORE_EXPORT virtual void getDebugBorderInfo(Color&, float& width) const; |
660 | |
661 | GraphicsLayerClient* m_client; // Always non-null. |
662 | String m_name; |
663 | |
664 | // Offset from the owning renderer |
665 | FloatSize m_offsetFromRenderer; |
666 | |
667 | // Scroll offset of the content layer inside its scrolling parent layer. |
668 | ScrollOffset m_scrollOffset; |
669 | |
670 | // Position is relative to the parent GraphicsLayer |
671 | FloatPoint m_position; |
672 | |
673 | // If set, overrides m_position. Only used for coverage computation. |
674 | Optional<FloatPoint> m_approximatePosition; |
675 | |
676 | FloatPoint3D m_anchorPoint { 0.5f, 0.5f, 0 }; |
677 | FloatSize m_size; |
678 | FloatPoint m_boundsOrigin; |
679 | |
680 | std::unique_ptr<TransformationMatrix> m_transform; |
681 | std::unique_ptr<TransformationMatrix> m_childrenTransform; |
682 | |
683 | Color m_backgroundColor; |
684 | float m_opacity { 1 }; |
685 | float m_zPosition { 0 }; |
686 | |
687 | FilterOperations m_filters; |
688 | FilterOperations m_backdropFilters; |
689 | |
690 | #if ENABLE(CSS_COMPOSITING) |
691 | BlendMode m_blendMode { BlendMode::Normal }; |
692 | #endif |
693 | |
694 | const Type m_type; |
695 | CustomAppearance m_customAppearance { CustomAppearance::None }; |
696 | OptionSet<GraphicsLayerPaintingPhase> m_paintingPhase { GraphicsLayerPaintingPhase::Foreground, GraphicsLayerPaintingPhase::Background }; |
697 | CompositingCoordinatesOrientation m_contentsOrientation { CompositingCoordinatesOrientation::TopDown }; // affects orientation of layer contents |
698 | |
699 | bool m_beingDestroyed : 1; |
700 | bool m_contentsOpaque : 1; |
701 | bool m_supportsSubpixelAntialiasedText : 1; |
702 | bool m_preserves3D: 1; |
703 | bool m_backfaceVisibility : 1; |
704 | bool m_masksToBounds : 1; |
705 | bool m_drawsContent : 1; |
706 | bool m_contentsVisible : 1; |
707 | bool m_acceleratesDrawing : 1; |
708 | bool m_usesDisplayListDrawing : 1; |
709 | bool m_appliesPageScale : 1; // Set for the layer which has the page scale applied to it. |
710 | bool m_showDebugBorder : 1; |
711 | bool m_showRepaintCounter : 1; |
712 | bool m_isMaskLayer : 1; |
713 | bool m_isTrackingDisplayListReplay : 1; |
714 | bool m_userInteractionEnabled : 1; |
715 | bool m_canDetachBackingStore : 1; |
716 | |
717 | int m_repaintCount { 0 }; |
718 | |
719 | Vector<Ref<GraphicsLayer>> m_children; |
720 | GraphicsLayer* m_parent { nullptr }; |
721 | |
722 | RefPtr<GraphicsLayer> m_maskLayer { nullptr }; // Reference to mask layer. |
723 | |
724 | RefPtr<GraphicsLayer> m_replicaLayer { nullptr }; // A layer that replicates this layer. We only allow one, for now. |
725 | // The replica is not parented; this is the primary reference to it. |
726 | GraphicsLayer* m_replicatedLayer { nullptr }; // For a replica layer, a reference to the original layer. |
727 | FloatPoint m_replicatedLayerPosition; // For a replica layer, the position of the replica. |
728 | |
729 | FloatRect m_contentsRect; |
730 | FloatRoundedRect m_contentsClippingRect; |
731 | FloatRoundedRect m_masksToBoundsRect; |
732 | FloatSize m_contentsTilePhase; |
733 | FloatSize m_contentsTileSize; |
734 | FloatRoundedRect m_backdropFiltersRect; |
735 | Optional<FloatRect> m_animationExtent; |
736 | |
737 | EventRegion m_eventRegion; |
738 | #if USE(CA) |
739 | WindRule m_shapeLayerWindRule { WindRule::NonZero }; |
740 | Path m_shapeLayerPath; |
741 | #endif |
742 | }; |
743 | |
744 | WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const WebCore::GraphicsLayerPaintingPhase); |
745 | WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const Vector<GraphicsLayer::PlatformLayerID>&); |
746 | WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const GraphicsLayer::CustomAppearance&); |
747 | |
748 | } // namespace WebCore |
749 | |
750 | #define SPECIALIZE_TYPE_TRAITS_GRAPHICSLAYER(ToValueTypeName, predicate) \ |
751 | SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \ |
752 | static bool isType(const WebCore::GraphicsLayer& layer) { return layer.predicate; } \ |
753 | SPECIALIZE_TYPE_TRAITS_END() |
754 | |
755 | #if ENABLE(TREE_DEBUGGING) |
756 | // Outside the WebCore namespace for ease of invocation from the debugger. |
757 | void showGraphicsLayerTree(const WebCore::GraphicsLayer* layer); |
758 | #endif |
759 | |