5d8658a65cd9b19b376cf593243c14e4922cd005
[WebKit-https.git] / Source / WebCore / platform / graphics / ca / GraphicsLayerCA.cpp
1 /*
2  * Copyright (C) 2010-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 #include "config.h"
27 #include "GraphicsLayerCA.h"
28
29 #if USE(CA)
30
31 #include "Animation.h"
32 #include "DisplayListRecorder.h"
33 #include "DisplayListReplayer.h"
34 #include "FloatConversion.h"
35 #include "FloatRect.h"
36 #include "GraphicsLayerFactory.h"
37 #include "Image.h"
38 #include "Logging.h"
39 #include "PlatformCAFilters.h"
40 #include "PlatformCALayer.h"
41 #include "PlatformScreen.h"
42 #include "Region.h"
43 #include "RotateTransformOperation.h"
44 #include "ScaleTransformOperation.h"
45 #include "TiledBacking.h"
46 #include "TransformState.h"
47 #include "TranslateTransformOperation.h"
48 #include <QuartzCore/CATransform3D.h>
49 #include <limits.h>
50 #include <pal/spi/cf/CFUtilitiesSPI.h>
51 #include <wtf/CheckedArithmetic.h>
52 #include <wtf/HexNumber.h>
53 #include <wtf/MathExtras.h>
54 #include <wtf/NeverDestroyed.h>
55 #include <wtf/PointerComparison.h>
56 #include <wtf/SetForScope.h>
57 #include <wtf/SystemTracing.h>
58 #include <wtf/text/StringConcatenateNumbers.h>
59 #include <wtf/text/TextStream.h>
60
61 #if PLATFORM(IOS_FAMILY)
62 #include "SystemMemory.h"
63 #include "WebCoreThread.h"
64 #endif
65
66 #if PLATFORM(COCOA)
67 #include "PlatformCAAnimationCocoa.h"
68 #include "PlatformCALayerCocoa.h"
69 #endif
70
71 #if PLATFORM(WIN)
72 #include "PlatformCAAnimationWin.h"
73 #include "PlatformCALayerWin.h"
74 #endif
75
76 #if COMPILER(MSVC)
77 // See https://msdn.microsoft.com/en-us/library/1wea5zwe.aspx
78 #pragma warning(disable: 4701)
79 #endif
80
81 namespace WebCore {
82
83 // The threshold width or height above which a tiled layer will be used. This should be
84 // large enough to avoid tiled layers for most GraphicsLayers, but less than the OpenGL
85 // texture size limit on all supported hardware.
86 #if PLATFORM(IOS_FAMILY)
87 static const int cMaxPixelDimension = 1280;
88 static const int cMaxPixelDimensionLowMemory = 1024;
89 static const int cMemoryLevelToUseSmallerPixelDimension = 35;
90 #else
91 static const int cMaxPixelDimension = 2048;
92 #endif
93
94 // Derived empirically: <rdar://problem/13401861>
95 static const unsigned cMaxLayerTreeDepth = 128;
96
97 // About 10 screens of an iPhone 6 Plus. <rdar://problem/44532782>
98 static const unsigned cMaxTotalBackdropFilterArea = 1242 * 2208 * 10;
99
100 // If we send a duration of 0 to CA, then it will use the default duration
101 // of 250ms. So send a very small value instead.
102 static const float cAnimationAlmostZeroDuration = 1e-3f;
103
104 static bool isTransformTypeTransformationMatrix(TransformOperation::OperationType transformType)
105 {
106     switch (transformType) {
107     case TransformOperation::SKEW_X:
108     case TransformOperation::SKEW_Y:
109     case TransformOperation::SKEW:
110     case TransformOperation::MATRIX:
111     case TransformOperation::ROTATE_3D:
112     case TransformOperation::MATRIX_3D:
113     case TransformOperation::PERSPECTIVE:
114     case TransformOperation::IDENTITY:
115     case TransformOperation::NONE:
116         return true;
117     default:
118         return false;
119     }
120 }
121
122 static bool isTransformTypeFloatPoint3D(TransformOperation::OperationType transformType)
123 {
124     switch (transformType) {
125     case TransformOperation::SCALE:
126     case TransformOperation::SCALE_3D:
127     case TransformOperation::TRANSLATE:
128     case TransformOperation::TRANSLATE_3D:
129         return true;
130     default:
131         return false;
132     }
133 }
134
135 static bool isTransformTypeNumber(TransformOperation::OperationType transformType)
136 {
137     return !isTransformTypeTransformationMatrix(transformType) && !isTransformTypeFloatPoint3D(transformType);
138 }
139
140 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const FloatSize& size, float& value)
141 {
142     switch (transformType) {
143     case TransformOperation::ROTATE:
144     case TransformOperation::ROTATE_X:
145     case TransformOperation::ROTATE_Y:
146         value = transformOp ? narrowPrecisionToFloat(deg2rad(downcast<RotateTransformOperation>(*transformOp).angle())) : 0;
147         break;
148     case TransformOperation::SCALE_X:
149         value = transformOp ? narrowPrecisionToFloat(downcast<ScaleTransformOperation>(*transformOp).x()) : 1;
150         break;
151     case TransformOperation::SCALE_Y:
152         value = transformOp ? narrowPrecisionToFloat(downcast<ScaleTransformOperation>(*transformOp).y()) : 1;
153         break;
154     case TransformOperation::SCALE_Z:
155         value = transformOp ? narrowPrecisionToFloat(downcast<ScaleTransformOperation>(*transformOp).z()) : 1;
156         break;
157     case TransformOperation::TRANSLATE_X:
158         value = transformOp ? narrowPrecisionToFloat(downcast<TranslateTransformOperation>(*transformOp).x(size)) : 0;
159         break;
160     case TransformOperation::TRANSLATE_Y:
161         value = transformOp ? narrowPrecisionToFloat(downcast<TranslateTransformOperation>(*transformOp).y(size)) : 0;
162         break;
163     case TransformOperation::TRANSLATE_Z:
164         value = transformOp ? narrowPrecisionToFloat(downcast<TranslateTransformOperation>(*transformOp).z(size)) : 0;
165         break;
166     default:
167         break;
168     }
169 }
170
171 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const FloatSize& size, FloatPoint3D& value)
172 {
173     switch (transformType) {
174     case TransformOperation::SCALE:
175     case TransformOperation::SCALE_3D: {
176         const auto* scaleTransformOp = downcast<ScaleTransformOperation>(transformOp);
177         value.setX(scaleTransformOp ? narrowPrecisionToFloat(scaleTransformOp->x()) : 1);
178         value.setY(scaleTransformOp ? narrowPrecisionToFloat(scaleTransformOp->y()) : 1);
179         value.setZ(scaleTransformOp ? narrowPrecisionToFloat(scaleTransformOp->z()) : 1);
180         break;
181     }
182     case TransformOperation::TRANSLATE:
183     case TransformOperation::TRANSLATE_3D: {
184         const auto* translateTransformOp = downcast<TranslateTransformOperation>(transformOp);
185         value.setX(translateTransformOp ? narrowPrecisionToFloat(translateTransformOp->x(size)) : 0);
186         value.setY(translateTransformOp ? narrowPrecisionToFloat(translateTransformOp->y(size)) : 0);
187         value.setZ(translateTransformOp ? narrowPrecisionToFloat(translateTransformOp->z(size)) : 0);
188         break;
189     }
190     default:
191         break;
192     }
193 }
194
195 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const FloatSize& size, TransformationMatrix& value)
196 {
197     switch (transformType) {
198     case TransformOperation::SKEW_X:
199     case TransformOperation::SKEW_Y:
200     case TransformOperation::SKEW:
201     case TransformOperation::MATRIX:
202     case TransformOperation::ROTATE_3D:
203     case TransformOperation::MATRIX_3D:
204     case TransformOperation::PERSPECTIVE:
205     case TransformOperation::IDENTITY:
206     case TransformOperation::NONE:
207         if (transformOp)
208             transformOp->apply(value, size);
209         else
210             value.makeIdentity();
211         break;
212     default:
213         break;
214     }
215 }
216
217 static PlatformCAAnimation::ValueFunctionType getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
218 {
219     // Use literal strings to avoid link-time dependency on those symbols.
220     switch (transformType) {
221     case TransformOperation::ROTATE_X:
222         return PlatformCAAnimation::RotateX;
223     case TransformOperation::ROTATE_Y:
224         return PlatformCAAnimation::RotateY;
225     case TransformOperation::ROTATE:
226         return PlatformCAAnimation::RotateZ;
227     case TransformOperation::SCALE_X:
228         return PlatformCAAnimation::ScaleX;
229     case TransformOperation::SCALE_Y:
230         return PlatformCAAnimation::ScaleY;
231     case TransformOperation::SCALE_Z:
232         return PlatformCAAnimation::ScaleZ;
233     case TransformOperation::TRANSLATE_X:
234         return PlatformCAAnimation::TranslateX;
235     case TransformOperation::TRANSLATE_Y:
236         return PlatformCAAnimation::TranslateY;
237     case TransformOperation::TRANSLATE_Z:
238         return PlatformCAAnimation::TranslateZ;
239     case TransformOperation::SCALE:
240     case TransformOperation::SCALE_3D:
241         return PlatformCAAnimation::Scale;
242     case TransformOperation::TRANSLATE:
243     case TransformOperation::TRANSLATE_3D:
244         return PlatformCAAnimation::Translate;
245     default:
246         return PlatformCAAnimation::NoValueFunction;
247     }
248 }
249
250 static ASCIILiteral propertyIdToString(AnimatedPropertyID property)
251 {
252     switch (property) {
253     case AnimatedPropertyTransform:
254         return "transform"_s;
255     case AnimatedPropertyOpacity:
256         return "opacity"_s;
257     case AnimatedPropertyBackgroundColor:
258         return "backgroundColor"_s;
259     case AnimatedPropertyFilter:
260         return "filters"_s;
261 #if ENABLE(FILTERS_LEVEL_2)
262     case AnimatedPropertyWebkitBackdropFilter:
263         return "backdropFilters"_s;
264 #endif
265     case AnimatedPropertyInvalid:
266         ASSERT_NOT_REACHED();
267     }
268     ASSERT_NOT_REACHED();
269     return ASCIILiteral::null();
270 }
271
272 static String animationIdentifier(const String& animationName, AnimatedPropertyID property, int index, int subIndex)
273 {
274     return makeString(animationName, '_', static_cast<unsigned>(property), '_', index, '_', subIndex);
275 }
276
277 static bool animationHasStepsTimingFunction(const KeyframeValueList& valueList, const Animation* anim)
278 {
279     if (is<StepsTimingFunction>(anim->timingFunction()))
280         return true;
281     
282     for (unsigned i = 0; i < valueList.size(); ++i) {
283         if (const TimingFunction* timingFunction = valueList.at(i).timingFunction()) {
284             if (is<StepsTimingFunction>(timingFunction))
285                 return true;
286         }
287     }
288
289     return false;
290 }
291
292 static inline bool supportsAcceleratedFilterAnimations()
293 {
294 #if PLATFORM(COCOA)
295     return true;
296 #else
297     return false;
298 #endif
299 }
300
301 bool GraphicsLayer::supportsLayerType(Type type)
302 {
303     switch (type) {
304     case Type::Normal:
305     case Type::PageTiledBacking:
306     case Type::ScrollContainer:
307     case Type::ScrolledContents:
308         return true;
309     case Type::Shape:
310 #if PLATFORM(COCOA)
311         // FIXME: we can use shaper layers on Windows when PlatformCALayerCocoa::setShapePath() etc are implemented.
312         return true;
313 #else
314         return false;
315 #endif
316     }
317     ASSERT_NOT_REACHED();
318     return false;
319 }
320
321 bool GraphicsLayer::supportsBackgroundColorContent()
322 {
323     return true;
324 }
325
326 bool GraphicsLayer::supportsSubpixelAntialiasedLayerText()
327 {
328 #if PLATFORM(MAC)
329     return true;
330 #else
331     return false;
332 #endif
333 }
334
335 Ref<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient& client, Type layerType)
336 {
337     if (factory) {
338         auto layer = factory->createGraphicsLayer(layerType, client);
339         layer->initialize(layerType);
340         return layer;
341     }
342     
343     auto layer = adoptRef(*new GraphicsLayerCA(layerType, client));
344     layer->initialize(layerType);
345     return WTFMove(layer);
346 }
347
348 bool GraphicsLayerCA::filtersCanBeComposited(const FilterOperations& filters)
349 {
350 #if PLATFORM(COCOA)
351     return PlatformCALayerCocoa::filtersCanBeComposited(filters);
352 #elif PLATFORM(WIN)
353     return PlatformCALayerWin::filtersCanBeComposited(filters);
354 #endif
355 }
356
357 Ref<PlatformCALayer> GraphicsLayerCA::createPlatformCALayer(PlatformCALayer::LayerType layerType, PlatformCALayerClient* owner)
358 {
359 #if PLATFORM(COCOA)
360     auto result = PlatformCALayerCocoa::create(layerType, owner);
361     
362     if (result->canHaveBackingStore())
363         result->setWantsDeepColorBackingStore(screenSupportsExtendedColor());
364     
365     return result;
366 #elif PLATFORM(WIN)
367     return PlatformCALayerWin::create(layerType, owner);
368 #endif
369 }
370     
371 Ref<PlatformCALayer> GraphicsLayerCA::createPlatformCALayer(PlatformLayer* platformLayer, PlatformCALayerClient* owner)
372 {
373 #if PLATFORM(COCOA)
374     return PlatformCALayerCocoa::create(platformLayer, owner);
375 #elif PLATFORM(WIN)
376     return PlatformCALayerWin::create(platformLayer, owner);
377 #endif
378 }
379
380 Ref<PlatformCALayer> GraphicsLayerCA::createPlatformCALayerForEmbeddedView(PlatformCALayer::LayerType layerType, GraphicsLayer::EmbeddedViewID, PlatformCALayerClient* owner)
381 {
382     return GraphicsLayerCA::createPlatformCALayer(layerType, owner);
383 }
384
385 Ref<PlatformCAAnimation> GraphicsLayerCA::createPlatformCAAnimation(PlatformCAAnimation::AnimationType type, const String& keyPath)
386 {
387 #if PLATFORM(COCOA)
388     return PlatformCAAnimationCocoa::create(type, keyPath);
389 #elif PLATFORM(WIN)
390     return PlatformCAAnimationWin::create(type, keyPath);
391 #endif
392 }
393
394 typedef HashMap<const GraphicsLayerCA*, std::pair<FloatRect, std::unique_ptr<DisplayList::DisplayList>>> LayerDisplayListHashMap;
395
396 static LayerDisplayListHashMap& layerDisplayListMap()
397 {
398     static NeverDestroyed<LayerDisplayListHashMap> sharedHashMap;
399     return sharedHashMap;
400 }
401
402 GraphicsLayerCA::GraphicsLayerCA(Type layerType, GraphicsLayerClient& client)
403     : GraphicsLayer(layerType, client)
404     , m_needsFullRepaint(false)
405     , m_usingBackdropLayerType(false)
406     , m_isViewportConstrained(false)
407     , m_intersectsCoverageRect(false)
408     , m_hasEverPainted(false)
409     , m_hasDescendantsWithRunningTransformAnimations(false)
410     , m_hasDescendantsWithUncommittedChanges(false)
411 {
412 }
413
414 void GraphicsLayerCA::initialize(Type layerType)
415 {
416     PlatformCALayer::LayerType platformLayerType;
417     switch (layerType) {
418     case Type::Normal:
419     case Type::ScrolledContents:
420         platformLayerType = PlatformCALayer::LayerType::LayerTypeWebLayer;
421         break;
422     case Type::PageTiledBacking:
423         platformLayerType = PlatformCALayer::LayerType::LayerTypePageTiledBackingLayer;
424         break;
425     case Type::ScrollContainer:
426         platformLayerType = PlatformCALayer::LayerType::LayerTypeScrollContainerLayer;
427         break;
428     case Type::Shape:
429         platformLayerType = PlatformCALayer::LayerType::LayerTypeShapeLayer;
430         break;
431     }
432     m_layer = createPlatformCALayer(platformLayerType, this);
433     noteLayerPropertyChanged(ContentsScaleChanged);
434 }
435
436 GraphicsLayerCA::~GraphicsLayerCA()
437 {
438     if (UNLIKELY(isTrackingDisplayListReplay()))
439         layerDisplayListMap().remove(this);
440
441     // Do cleanup while we can still safely call methods on the derived class.
442     willBeDestroyed();
443 }
444
445 void GraphicsLayerCA::willBeDestroyed()
446 {
447     // We release our references to the PlatformCALayers here, but do not actively unparent them,
448     // since that will cause a commit and break our batched commit model. The layers will
449     // get released when the rootmost modified GraphicsLayerCA rebuilds its child layers.
450
451     // Clean up the layer.
452     if (m_layer)
453         m_layer->setOwner(nullptr);
454     
455     if (m_contentsLayer)
456         m_contentsLayer->setOwner(nullptr);
457
458     if (m_contentsClippingLayer)
459         m_contentsClippingLayer->setOwner(nullptr);
460
461     if (m_contentsShapeMaskLayer)
462         m_contentsShapeMaskLayer->setOwner(nullptr);
463
464     if (m_shapeMaskLayer)
465         m_shapeMaskLayer->setOwner(nullptr);
466     
467     if (m_structuralLayer)
468         m_structuralLayer->setOwner(nullptr);
469
470     if (m_backdropLayer)
471         m_backdropLayer->setOwner(nullptr);
472
473     if (m_backdropClippingLayer)
474         m_backdropClippingLayer->setOwner(nullptr);
475
476     removeCloneLayers();
477
478     GraphicsLayer::willBeDestroyed();
479 }
480
481 void GraphicsLayerCA::setName(const String& name)
482 {
483 #if ENABLE(TREE_DEBUGGING)
484     String caLayerDescription;
485     if (!m_layer->isPlatformCALayerRemote())
486         caLayerDescription = makeString("CALayer(0x", hex(reinterpret_cast<uintptr_t>(m_layer->platformLayer()), Lowercase), ") ");
487     GraphicsLayer::setName(makeString(caLayerDescription, "GraphicsLayer(0x", hex(reinterpret_cast<uintptr_t>(this), Lowercase), ", ", primaryLayerID(), ") ", name));
488 #else
489     GraphicsLayer::setName(name);
490 #endif
491
492     noteLayerPropertyChanged(NameChanged);
493 }
494
495 GraphicsLayer::PlatformLayerID GraphicsLayerCA::primaryLayerID() const
496 {
497     return primaryLayer()->layerID();
498 }
499
500 PlatformLayer* GraphicsLayerCA::platformLayer() const
501 {
502     return primaryLayer()->platformLayer();
503 }
504
505 bool GraphicsLayerCA::setChildren(Vector<Ref<GraphicsLayer>>&& children)
506 {
507     bool childrenChanged = GraphicsLayer::setChildren(WTFMove(children));
508     if (childrenChanged)
509         noteSublayersChanged();
510     
511     return childrenChanged;
512 }
513
514 void GraphicsLayerCA::addChild(Ref<GraphicsLayer>&& childLayer)
515 {
516     GraphicsLayer::addChild(WTFMove(childLayer));
517     noteSublayersChanged();
518 }
519
520 void GraphicsLayerCA::addChildAtIndex(Ref<GraphicsLayer>&& childLayer, int index)
521 {
522     GraphicsLayer::addChildAtIndex(WTFMove(childLayer), index);
523     noteSublayersChanged();
524 }
525
526 void GraphicsLayerCA::addChildBelow(Ref<GraphicsLayer>&& childLayer, GraphicsLayer* sibling)
527 {
528     GraphicsLayer::addChildBelow(WTFMove(childLayer), sibling);
529     noteSublayersChanged();
530 }
531
532 void GraphicsLayerCA::addChildAbove(Ref<GraphicsLayer>&& childLayer, GraphicsLayer* sibling)
533 {
534     GraphicsLayer::addChildAbove(WTFMove(childLayer), sibling);
535     noteSublayersChanged();
536 }
537
538 bool GraphicsLayerCA::replaceChild(GraphicsLayer* oldChild, Ref<GraphicsLayer>&& newChild)
539 {
540     if (GraphicsLayer::replaceChild(oldChild, WTFMove(newChild))) {
541         noteSublayersChanged();
542         return true;
543     }
544     return false;
545 }
546
547 void GraphicsLayerCA::removeFromParent()
548 {
549     if (m_parent)
550         downcast<GraphicsLayerCA>(*m_parent).noteSublayersChanged();
551     GraphicsLayer::removeFromParent();
552 }
553
554 void GraphicsLayerCA::setMaskLayer(RefPtr<GraphicsLayer>&& layer)
555 {
556     if (layer == m_maskLayer)
557         return;
558
559     GraphicsLayer::setMaskLayer(WTFMove(layer));
560     noteLayerPropertyChanged(MaskLayerChanged);
561
562     propagateLayerChangeToReplicas();
563     
564     if (m_replicatedLayer)
565         downcast<GraphicsLayerCA>(*m_replicatedLayer).propagateLayerChangeToReplicas();
566 }
567
568 void GraphicsLayerCA::setReplicatedLayer(GraphicsLayer* layer)
569 {
570     if (layer == m_replicatedLayer)
571         return;
572
573     GraphicsLayer::setReplicatedLayer(layer);
574     noteLayerPropertyChanged(ReplicatedLayerChanged);
575 }
576
577 void GraphicsLayerCA::setReplicatedByLayer(RefPtr<GraphicsLayer>&& layer)
578 {
579     if (layer == m_replicaLayer)
580         return;
581
582     GraphicsLayer::setReplicatedByLayer(WTFMove(layer));
583     noteSublayersChanged();
584     noteLayerPropertyChanged(ReplicatedLayerChanged);
585 }
586
587 void GraphicsLayerCA::setPosition(const FloatPoint& point)
588 {
589     if (point == m_position)
590         return;
591
592     GraphicsLayer::setPosition(point);
593     noteLayerPropertyChanged(GeometryChanged);
594 }
595
596 void GraphicsLayerCA::syncPosition(const FloatPoint& point)
597 {
598     if (point == m_position)
599         return;
600
601     GraphicsLayer::syncPosition(point);
602     // Ensure future flushes will recompute the coverage rect and update tiling.
603     noteLayerPropertyChanged(NeedsComputeVisibleAndCoverageRect, DontScheduleFlush);
604 }
605
606 void GraphicsLayerCA::setApproximatePosition(const FloatPoint& point)
607 {
608     if (point == m_approximatePosition)
609         return;
610
611     GraphicsLayer::setApproximatePosition(point);
612     // Ensure future flushes will recompute the coverage rect and update tiling.
613     noteLayerPropertyChanged(NeedsComputeVisibleAndCoverageRect, DontScheduleFlush);
614 }
615
616 void GraphicsLayerCA::setAnchorPoint(const FloatPoint3D& point)
617 {
618     if (point == m_anchorPoint)
619         return;
620
621     GraphicsLayer::setAnchorPoint(point);
622     noteLayerPropertyChanged(GeometryChanged);
623 }
624
625 void GraphicsLayerCA::setSize(const FloatSize& size)
626 {
627     if (size == m_size)
628         return;
629
630     GraphicsLayer::setSize(size);
631     noteLayerPropertyChanged(GeometryChanged);
632 }
633
634 void GraphicsLayerCA::setBoundsOrigin(const FloatPoint& origin)
635 {
636     if (origin == m_boundsOrigin)
637         return;
638
639     GraphicsLayer::setBoundsOrigin(origin);
640     noteLayerPropertyChanged(GeometryChanged);
641 }
642
643 void GraphicsLayerCA::syncBoundsOrigin(const FloatPoint& origin)
644 {
645     if (origin == m_boundsOrigin)
646         return;
647
648     GraphicsLayer::syncBoundsOrigin(origin);
649     noteLayerPropertyChanged(NeedsComputeVisibleAndCoverageRect, DontScheduleFlush);
650 }
651
652 void GraphicsLayerCA::setTransform(const TransformationMatrix& t)
653 {
654     if (t == transform())
655         return;
656
657     GraphicsLayer::setTransform(t);
658     noteLayerPropertyChanged(TransformChanged);
659 }
660
661 void GraphicsLayerCA::setChildrenTransform(const TransformationMatrix& t)
662 {
663     if (t == childrenTransform())
664         return;
665
666     GraphicsLayer::setChildrenTransform(t);
667     noteLayerPropertyChanged(ChildrenTransformChanged);
668 }
669
670 void GraphicsLayerCA::moveOrCopyLayerAnimation(MoveOrCopy operation, const String& animationIdentifier, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
671 {
672     RefPtr<PlatformCAAnimation> anim = fromLayer->animationForKey(animationIdentifier);
673     if (!anim)
674         return;
675
676     switch (operation) {
677     case Move:
678         fromLayer->removeAnimationForKey(animationIdentifier);
679         toLayer->addAnimationForKey(animationIdentifier, *anim);
680         break;
681
682     case Copy:
683         toLayer->addAnimationForKey(animationIdentifier, *anim);
684         break;
685     }
686 }
687
688 void GraphicsLayerCA::moveOrCopyAnimations(MoveOrCopy operation, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
689 {
690     if (!hasAnimations())
691         return;
692
693     // Look for running animations affecting this property.
694     for (const auto& it : m_animations->runningAnimations) {
695         const auto& propertyAnimations = it.value;
696         size_t numAnimations = propertyAnimations.size();
697         for (size_t i = 0; i < numAnimations; ++i) {
698             const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
699
700             if (currAnimation.m_property == AnimatedPropertyTransform
701                 || currAnimation.m_property == AnimatedPropertyOpacity
702                 || currAnimation.m_property == AnimatedPropertyBackgroundColor
703                 || currAnimation.m_property == AnimatedPropertyFilter)
704                 moveOrCopyLayerAnimation(operation, animationIdentifier(currAnimation.m_name, currAnimation.m_property, currAnimation.m_index, currAnimation.m_subIndex), fromLayer, toLayer);
705         }
706     }
707 }
708
709 void GraphicsLayerCA::setPreserves3D(bool preserves3D)
710 {
711     if (preserves3D == m_preserves3D)
712         return;
713
714     GraphicsLayer::setPreserves3D(preserves3D);
715     noteLayerPropertyChanged(Preserves3DChanged);
716 }
717
718 void GraphicsLayerCA::setMasksToBounds(bool masksToBounds)
719 {
720     if (masksToBounds == m_masksToBounds)
721         return;
722
723     GraphicsLayer::setMasksToBounds(masksToBounds);
724     noteLayerPropertyChanged(MasksToBoundsChanged | DebugIndicatorsChanged);
725 }
726
727 void GraphicsLayerCA::setDrawsContent(bool drawsContent)
728 {
729     if (drawsContent == m_drawsContent)
730         return;
731
732     GraphicsLayer::setDrawsContent(drawsContent);
733     noteLayerPropertyChanged(DrawsContentChanged | DebugIndicatorsChanged);
734 }
735
736 void GraphicsLayerCA::setContentsVisible(bool contentsVisible)
737 {
738     if (contentsVisible == m_contentsVisible)
739         return;
740
741     GraphicsLayer::setContentsVisible(contentsVisible);
742     noteLayerPropertyChanged(ContentsVisibilityChanged);
743     // Visibility affects whether the contentsLayer is parented.
744     if (m_contentsLayer)
745         noteSublayersChanged();
746 }
747
748 void GraphicsLayerCA::setUserInteractionEnabled(bool userInteractionEnabled)
749 {
750     if (userInteractionEnabled == m_userInteractionEnabled)
751         return;
752     
753     GraphicsLayer::setUserInteractionEnabled(userInteractionEnabled);
754     noteLayerPropertyChanged(UserInteractionEnabledChanged);
755 }
756
757 void GraphicsLayerCA::setAcceleratesDrawing(bool acceleratesDrawing)
758 {
759     if (acceleratesDrawing == m_acceleratesDrawing)
760         return;
761
762     GraphicsLayer::setAcceleratesDrawing(acceleratesDrawing);
763     noteLayerPropertyChanged(AcceleratesDrawingChanged);
764 }
765
766 void GraphicsLayerCA::setUsesDisplayListDrawing(bool usesDisplayListDrawing)
767 {
768     if (usesDisplayListDrawing == m_usesDisplayListDrawing)
769         return;
770
771     setNeedsDisplay();
772     GraphicsLayer::setUsesDisplayListDrawing(usesDisplayListDrawing);
773 }
774
775 void GraphicsLayerCA::setBackgroundColor(const Color& color)
776 {
777     if (m_backgroundColor == color)
778         return;
779
780     GraphicsLayer::setBackgroundColor(color);
781     noteLayerPropertyChanged(BackgroundColorChanged);
782 }
783
784 void GraphicsLayerCA::setContentsOpaque(bool opaque)
785 {
786     if (m_contentsOpaque == opaque)
787         return;
788
789     GraphicsLayer::setContentsOpaque(opaque);
790     noteLayerPropertyChanged(ContentsOpaqueChanged);
791 }
792
793 void GraphicsLayerCA::setSupportsSubpixelAntialiasedText(bool supportsSubpixelAntialiasedText)
794 {
795     if (m_supportsSubpixelAntialiasedText == supportsSubpixelAntialiasedText)
796         return;
797
798     GraphicsLayer::setSupportsSubpixelAntialiasedText(supportsSubpixelAntialiasedText);
799     noteLayerPropertyChanged(SupportsSubpixelAntialiasedTextChanged);
800 }
801
802 void GraphicsLayerCA::setBackfaceVisibility(bool visible)
803 {
804     if (m_backfaceVisibility == visible)
805         return;
806     
807     GraphicsLayer::setBackfaceVisibility(visible);
808     noteLayerPropertyChanged(BackfaceVisibilityChanged);
809 }
810
811 void GraphicsLayerCA::setOpacity(float opacity)
812 {
813     float clampedOpacity = std::max(0.0f, std::min(opacity, 1.0f));
814
815     if (clampedOpacity == m_opacity)
816         return;
817
818     GraphicsLayer::setOpacity(clampedOpacity);
819     noteLayerPropertyChanged(OpacityChanged);
820 }
821
822 bool GraphicsLayerCA::setFilters(const FilterOperations& filterOperations)
823 {
824     bool canCompositeFilters = filtersCanBeComposited(filterOperations);
825
826     if (m_filters == filterOperations)
827         return canCompositeFilters;
828
829     // Filters cause flattening, so we should never have filters on a layer with preserves3D().
830     ASSERT(!filterOperations.size() || !preserves3D());
831
832     if (canCompositeFilters) {
833         GraphicsLayer::setFilters(filterOperations);
834         noteLayerPropertyChanged(FiltersChanged);
835     } else if (filters().size()) {
836         // In this case filters are rendered in software, so we need to remove any 
837         // previously attached hardware filters.
838         clearFilters();
839         noteLayerPropertyChanged(FiltersChanged);
840     }
841     return canCompositeFilters;
842 }
843
844 bool GraphicsLayerCA::setBackdropFilters(const FilterOperations& filterOperations)
845 {
846     bool canCompositeFilters = filtersCanBeComposited(filterOperations);
847
848     if (m_backdropFilters == filterOperations)
849         return canCompositeFilters;
850
851     // Filters cause flattening, so we should never have filters on a layer with preserves3D().
852     ASSERT(!filterOperations.size() || !preserves3D());
853
854     if (canCompositeFilters)
855         GraphicsLayer::setBackdropFilters(filterOperations);
856     else {
857         // FIXME: This would clear the backdrop filters if we had a software implementation.
858         clearBackdropFilters();
859     }
860
861     noteLayerPropertyChanged(BackdropFiltersChanged | DebugIndicatorsChanged);
862     return canCompositeFilters;
863 }
864
865 void GraphicsLayerCA::setBackdropFiltersRect(const FloatRoundedRect& backdropFiltersRect)
866 {
867     if (backdropFiltersRect == m_backdropFiltersRect)
868         return;
869
870     GraphicsLayer::setBackdropFiltersRect(backdropFiltersRect);
871     noteLayerPropertyChanged(BackdropFiltersRectChanged);
872 }
873
874 #if ENABLE(CSS_COMPOSITING)
875 void GraphicsLayerCA::setBlendMode(BlendMode blendMode)
876 {
877     if (GraphicsLayer::blendMode() == blendMode)
878         return;
879
880     GraphicsLayer::setBlendMode(blendMode);
881     noteLayerPropertyChanged(BlendModeChanged);
882 }
883 #endif
884
885 bool GraphicsLayerCA::backingStoreAttached() const
886 {
887     return m_layer->backingStoreAttached();
888 }
889
890 bool GraphicsLayerCA::backingStoreAttachedForTesting() const
891 {
892     return m_layer->backingStoreAttached() || m_layer->hasContents();
893 }
894
895 void GraphicsLayerCA::setNeedsDisplay()
896 {
897     if (!drawsContent())
898         return;
899
900     m_needsFullRepaint = true;
901     m_dirtyRects.clear();
902     noteLayerPropertyChanged(DirtyRectsChanged);
903     addRepaintRect(FloatRect(FloatPoint(), m_size));
904 }
905
906 void GraphicsLayerCA::setNeedsDisplayInRect(const FloatRect& r, ShouldClipToLayer shouldClip)
907 {
908     if (!drawsContent())
909         return;
910
911     if (m_needsFullRepaint)
912         return;
913
914     FloatRect rect(r);
915     if (shouldClip == ClipToLayer) {
916         FloatRect layerBounds(FloatPoint(), m_size);
917         rect.intersect(layerBounds);
918     }
919
920     if (rect.isEmpty())
921         return;
922
923     addRepaintRect(rect);
924
925     const size_t maxDirtyRects = 32;
926
927     for (size_t i = 0; i < m_dirtyRects.size(); ++i) {
928         if (m_dirtyRects[i].contains(rect))
929             return;
930     }
931
932     if (m_dirtyRects.size() < maxDirtyRects)
933         m_dirtyRects.append(rect);
934     else
935         m_dirtyRects[0].unite(rect);
936
937     noteLayerPropertyChanged(DirtyRectsChanged);
938 }
939
940 void GraphicsLayerCA::setContentsNeedsDisplay()
941 {
942     noteLayerPropertyChanged(ContentsNeedsDisplay);
943 }
944
945 void GraphicsLayerCA::setContentsRect(const FloatRect& rect)
946 {
947     if (rect == m_contentsRect)
948         return;
949
950     GraphicsLayer::setContentsRect(rect);
951     noteLayerPropertyChanged(ContentsRectsChanged);
952 }
953
954 void GraphicsLayerCA::setContentsClippingRect(const FloatRoundedRect& rect)
955 {
956     if (rect == m_contentsClippingRect)
957         return;
958
959     GraphicsLayer::setContentsClippingRect(rect);
960     noteLayerPropertyChanged(ContentsRectsChanged);
961 }
962
963 bool GraphicsLayerCA::setMasksToBoundsRect(const FloatRoundedRect& roundedRect)
964 {
965     if (roundedRect == m_masksToBoundsRect)
966         return true;
967
968     GraphicsLayer::setMasksToBoundsRect(roundedRect);
969     noteLayerPropertyChanged(MasksToBoundsRectChanged);
970     return true;
971 }
972
973 void GraphicsLayerCA::setShapeLayerPath(const Path& path)
974 {
975     // FIXME: need to check for path equality. No bool Path::operator==(const Path&)!.
976     GraphicsLayer::setShapeLayerPath(path);
977     noteLayerPropertyChanged(ShapeChanged);
978 }
979
980 void GraphicsLayerCA::setShapeLayerWindRule(WindRule windRule)
981 {
982     if (windRule == m_shapeLayerWindRule)
983         return;
984
985     GraphicsLayer::setShapeLayerWindRule(windRule);
986     noteLayerPropertyChanged(WindRuleChanged);
987 }
988
989 void GraphicsLayerCA::setEventRegion(EventRegion&& eventRegion)
990 {
991     if (eventRegion == m_eventRegion)
992         return;
993
994     GraphicsLayer::setEventRegion(WTFMove(eventRegion));
995     noteLayerPropertyChanged(EventRegionChanged, m_isCommittingChanges ? DontScheduleFlush : ScheduleFlush);
996 }
997
998 bool GraphicsLayerCA::shouldRepaintOnSizeChange() const
999 {
1000     return drawsContent() && !tiledBacking();
1001 }
1002
1003 bool GraphicsLayerCA::animationCanBeAccelerated(const KeyframeValueList& valueList, const Animation* anim) const
1004 {
1005     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
1006         return false;
1007
1008     if (animationHasStepsTimingFunction(valueList, anim))
1009         return false;
1010
1011     return true;
1012 }
1013
1014 void GraphicsLayerCA::addProcessingActionForAnimation(const String& animationName, AnimationProcessingAction processingAction)
1015 {
1016     ensureLayerAnimations();
1017
1018     auto& processingActions = m_animations->animationsToProcess.ensure(animationName, [] {
1019         return Vector<AnimationProcessingAction> { };
1020     }).iterator->value;
1021
1022     if (!processingActions.isEmpty() && processingActions.last().action == Remove)
1023         return;
1024
1025     processingActions.append(processingAction);
1026 }
1027
1028 bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const FloatSize& boxSize, const Animation* anim, const String& animationName, double timeOffset)
1029 {
1030     LOG(Animations, "GraphicsLayerCA %p %llu addAnimation %s (can be accelerated %d)", this, primaryLayerID(), animationName.utf8().data(), animationCanBeAccelerated(valueList, anim));
1031
1032     ASSERT(!animationName.isEmpty());
1033
1034     if (!animationCanBeAccelerated(valueList, anim))
1035         return false;
1036
1037     bool createdAnimations = false;
1038     if (valueList.property() == AnimatedPropertyTransform)
1039         createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, animationName, Seconds { timeOffset }, boxSize);
1040     else if (valueList.property() == AnimatedPropertyFilter) {
1041         if (supportsAcceleratedFilterAnimations())
1042             createdAnimations = createFilterAnimationsFromKeyframes(valueList, anim, animationName, Seconds { timeOffset });
1043     }
1044 #if ENABLE(FILTERS_LEVEL_2)
1045     else if (valueList.property() == AnimatedPropertyWebkitBackdropFilter) {
1046         if (supportsAcceleratedFilterAnimations())
1047             createdAnimations = createFilterAnimationsFromKeyframes(valueList, anim, animationName, Seconds { timeOffset });
1048     }
1049 #endif
1050     else
1051         createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, Seconds { timeOffset });
1052
1053     if (createdAnimations)
1054         noteLayerPropertyChanged(AnimationChanged | CoverageRectChanged);
1055
1056     return createdAnimations;
1057 }
1058
1059 void GraphicsLayerCA::pauseAnimation(const String& animationName, double timeOffset)
1060 {
1061     LOG(Animations, "GraphicsLayerCA %p pauseAnimation %s (running %d)", this, animationName.utf8().data(), animationIsRunning(animationName));
1062
1063     // Call add since if there is already a Remove in there, we don't want to overwrite it with a Pause.
1064     addProcessingActionForAnimation(animationName, AnimationProcessingAction { Pause, Seconds { timeOffset } });
1065
1066     noteLayerPropertyChanged(AnimationChanged);
1067 }
1068
1069 void GraphicsLayerCA::seekAnimation(const String& animationName, double timeOffset)
1070 {
1071     LOG(Animations, "GraphicsLayerCA %p seekAnimation %s (running %d)", this, animationName.utf8().data(), animationIsRunning(animationName));
1072
1073     // Call add since if there is already a Remove in there, we don't want to overwrite it with a Pause.
1074     addProcessingActionForAnimation(animationName, AnimationProcessingAction { Seek, Seconds { timeOffset } });
1075
1076     noteLayerPropertyChanged(AnimationChanged);
1077 }
1078
1079 void GraphicsLayerCA::removeAnimation(const String& animationName)
1080 {
1081     LOG(Animations, "GraphicsLayerCA %p removeAnimation %s (running %d)", this, animationName.utf8().data(), animationIsRunning(animationName));
1082
1083     if (!animationIsRunning(animationName))
1084         return;
1085
1086     addProcessingActionForAnimation(animationName, AnimationProcessingAction(Remove));
1087     noteLayerPropertyChanged(AnimationChanged | CoverageRectChanged);
1088 }
1089
1090 void GraphicsLayerCA::platformCALayerAnimationStarted(const String& animationKey, MonotonicTime startTime)
1091 {
1092     LOG(Animations, "GraphicsLayerCA %p platformCALayerAnimationStarted %s at %f", this, animationKey.utf8().data(), startTime.secondsSinceEpoch().seconds());
1093     client().notifyAnimationStarted(this, animationKey, startTime);
1094 }
1095
1096 void GraphicsLayerCA::platformCALayerAnimationEnded(const String& animationKey)
1097 {
1098     LOG(Animations, "GraphicsLayerCA %p platformCALayerAnimationEnded %s", this, animationKey.utf8().data());
1099     client().notifyAnimationEnded(this, animationKey);
1100 }
1101
1102 void GraphicsLayerCA::setContentsToSolidColor(const Color& color)
1103 {
1104     if (color == m_contentsSolidColor)
1105         return;
1106
1107     m_contentsSolidColor = color;
1108     
1109     bool contentsLayerChanged = false;
1110
1111     if (m_contentsSolidColor.isVisible()) {
1112         if (!m_contentsLayer || m_contentsLayerPurpose != ContentsLayerPurpose::BackgroundColor) {
1113             m_contentsLayerPurpose = ContentsLayerPurpose::BackgroundColor;
1114             m_contentsLayer = createPlatformCALayer(PlatformCALayer::LayerTypeLayer, this);
1115 #if ENABLE(TREE_DEBUGGING)
1116             m_contentsLayer->setName(makeString("contents color ", m_contentsLayer->layerID()));
1117 #else
1118             m_contentsLayer->setName("contents color");
1119 #endif
1120             contentsLayerChanged = true;
1121         }
1122     } else {
1123         contentsLayerChanged = m_contentsLayer;
1124         m_contentsLayerPurpose = ContentsLayerPurpose::None;
1125         m_contentsLayer = nullptr;
1126     }
1127
1128     if (contentsLayerChanged)
1129         noteSublayersChanged();
1130
1131     noteLayerPropertyChanged(ContentsColorLayerChanged);
1132 }
1133
1134 void GraphicsLayerCA::setContentsToImage(Image* image)
1135 {
1136     if (image) {
1137         auto newImage = image->nativeImageForCurrentFrame();
1138         if (!newImage)
1139             return;
1140
1141         // FIXME: probably don't need m_uncorrectedContentsImage at all now.
1142         if (m_uncorrectedContentsImage == newImage)
1143             return;
1144         
1145         m_uncorrectedContentsImage = WTFMove(newImage);
1146         m_pendingContentsImage = m_uncorrectedContentsImage;
1147
1148         m_contentsLayerPurpose = ContentsLayerPurpose::Image;
1149         if (!m_contentsLayer)
1150             noteSublayersChanged();
1151     } else {
1152         m_uncorrectedContentsImage = nullptr;
1153         m_pendingContentsImage = nullptr;
1154         m_contentsLayerPurpose = ContentsLayerPurpose::None;
1155         if (m_contentsLayer)
1156             noteSublayersChanged();
1157     }
1158
1159     noteLayerPropertyChanged(ContentsImageChanged);
1160 }
1161
1162 void GraphicsLayerCA::setContentsToEmbeddedView(GraphicsLayer::ContentsLayerEmbeddedViewType layerType, GraphicsLayer::EmbeddedViewID embeddedViewID)
1163 {
1164     bool contentsLayerChanged = false;
1165
1166     if (layerType != GraphicsLayer::ContentsLayerEmbeddedViewType::None) {
1167         m_contentsLayerPurpose = ContentsLayerPurpose::EmbeddedView;
1168
1169         PlatformCALayer::LayerType platformType;
1170         switch (layerType) {
1171         case GraphicsLayer::ContentsLayerEmbeddedViewType::EditableImage:
1172             platformType = PlatformCALayer::LayerTypeEditableImageLayer;
1173             break;
1174         default:
1175             ASSERT_NOT_REACHED();
1176             platformType = PlatformCALayer::LayerTypeLayer;
1177             break;
1178         }
1179
1180         if (!m_contentsLayer || m_contentsLayer->layerType() != platformType || m_contentsLayer->embeddedViewID() != embeddedViewID) {
1181             m_contentsLayer = createPlatformCALayerForEmbeddedView(platformType, embeddedViewID, this);
1182             m_contentsLayer->setAnchorPoint(FloatPoint3D());
1183             contentsLayerChanged = true;
1184         }
1185     } else {
1186         m_contentsLayerPurpose = ContentsLayerPurpose::None;
1187         contentsLayerChanged = m_contentsLayer;
1188         m_contentsLayer = nullptr;
1189     }
1190
1191     if (contentsLayerChanged)
1192         noteSublayersChanged();
1193 }
1194
1195 void GraphicsLayerCA::setContentsToPlatformLayer(PlatformLayer* platformLayer, ContentsLayerPurpose purpose)
1196 {
1197     if (m_contentsLayer && platformLayer == m_contentsLayer->platformLayer())
1198         return;
1199
1200     if (m_contentsClippingLayer && m_contentsLayer)
1201         m_contentsLayer->removeFromSuperlayer();
1202
1203     // FIXME: The passed in layer might be a raw layer or an externally created
1204     // PlatformCALayer. To determine this we attempt to get the
1205     // PlatformCALayer pointer. If this returns a null pointer we assume it's
1206     // raw. This test might be invalid if the raw layer is, for instance, the
1207     // PlatformCALayer is using a user data pointer in the raw layer, and
1208     // the creator of the raw layer is using it for some other purpose.
1209     // For now we don't support such a case.
1210     PlatformCALayer* platformCALayer = PlatformCALayer::platformCALayer(platformLayer);
1211     m_contentsLayer = platformLayer ? (platformCALayer ? platformCALayer : createPlatformCALayer(platformLayer, this).ptr()) : nullptr;
1212     m_contentsLayerPurpose = platformLayer ? purpose : ContentsLayerPurpose::None;
1213
1214     if (m_contentsClippingLayer && m_contentsLayer)
1215         m_contentsClippingLayer->appendSublayer(*m_contentsLayer);
1216
1217     noteSublayersChanged();
1218     noteLayerPropertyChanged(ContentsPlatformLayerChanged);
1219 }
1220
1221 #if PLATFORM(IOS_FAMILY)
1222 PlatformLayer* GraphicsLayerCA::contentsLayerForMedia() const
1223 {
1224     return m_contentsLayerPurpose == ContentsLayerPurpose::Media ? m_contentsLayer->platformLayer() : nullptr;
1225 }
1226 #endif
1227
1228 void GraphicsLayerCA::layerDidDisplay(PlatformCALayer* layer)
1229 {
1230     if (!m_layerClones)
1231         return;
1232
1233     LayerMap* layerCloneMap = nullptr;
1234
1235     if (layer == m_layer)
1236         layerCloneMap = &m_layerClones->primaryLayerClones;
1237     else if (layer == m_contentsLayer)
1238         layerCloneMap = &m_layerClones->contentsLayerClones;
1239
1240     if (layerCloneMap) {
1241         for (auto& platformLayerClone : layerCloneMap->values())
1242             platformLayerClone->copyContentsFromLayer(layer);
1243     }
1244 }
1245
1246 FloatPoint GraphicsLayerCA::computePositionRelativeToBase(float& pageScale) const
1247 {
1248     pageScale = 1;
1249
1250     FloatPoint offset;
1251     for (const GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) {
1252         if (currLayer->appliesPageScale()) {
1253             pageScale = currLayer->pageScaleFactor();
1254             return offset;
1255         }
1256
1257         offset += currLayer->position();
1258     }
1259
1260     return FloatPoint();
1261 }
1262
1263 void GraphicsLayerCA::flushCompositingState(const FloatRect& visibleRect)
1264 {
1265     TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(visibleRect));
1266     FloatQuad coverageQuad(visibleRect);
1267     state.setSecondaryQuad(&coverageQuad);
1268
1269     CommitState commitState;
1270     commitState.ancestorHadChanges = visibleRect != m_previousCommittedVisibleRect;
1271     m_previousCommittedVisibleRect = visibleRect;
1272
1273 #if PLATFORM(IOS_FAMILY)
1274     // In WK1, UIKit may be changing layer bounds behind our back in overflow-scroll layers, so disable the optimization.
1275     // See the similar test in computeVisibleAndCoverageRect().
1276     if (m_layer->isPlatformCALayerCocoa())
1277         commitState.ancestorHadChanges = true;
1278 #endif
1279
1280     recursiveCommitChanges(commitState, state);
1281 }
1282
1283 void GraphicsLayerCA::flushCompositingStateForThisLayerOnly()
1284 {
1285     float pageScaleFactor;
1286     bool layerTypeChanged = false;
1287     
1288     CommitState commitState;
1289
1290     FloatPoint offset = computePositionRelativeToBase(pageScaleFactor);
1291     commitLayerChangesBeforeSublayers(commitState, pageScaleFactor, offset, layerTypeChanged);
1292     commitLayerChangesAfterSublayers(commitState);
1293
1294     if (layerTypeChanged)
1295         client().didChangePlatformLayerForLayer(this);
1296 }
1297
1298 static inline bool accumulatesTransform(const GraphicsLayerCA& layer)
1299 {
1300     return !layer.masksToBounds() && (layer.preserves3D() || (layer.parent() && layer.parent()->preserves3D()));
1301 }
1302
1303 bool GraphicsLayerCA::recursiveVisibleRectChangeRequiresFlush(const CommitState& commitState, const TransformState& state) const
1304 {
1305     TransformState localState = state;
1306     CommitState childCommitState = commitState;
1307
1308     // This may be called at times when layout has not been updated, so we want to avoid calling out to the client
1309     // for animating transforms.
1310     VisibleAndCoverageRects rects = computeVisibleAndCoverageRect(localState, accumulatesTransform(*this), 0);
1311     adjustCoverageRect(rects, m_visibleRect);
1312
1313     auto bounds = FloatRect(m_boundsOrigin, size());
1314
1315     bool isViewportConstrained = m_isViewportConstrained || commitState.ancestorIsViewportConstrained;
1316     bool intersectsCoverageRect = isViewportConstrained || rects.coverageRect.intersects(bounds);
1317     if (intersectsCoverageRect != m_intersectsCoverageRect)
1318         return true;
1319
1320     if (rects.coverageRect != m_coverageRect) {
1321         if (TiledBacking* tiledBacking = this->tiledBacking()) {
1322             if (tiledBacking->tilesWouldChangeForCoverageRect(rects.coverageRect))
1323                 return true;
1324         }
1325     }
1326
1327     childCommitState.ancestorIsViewportConstrained |= m_isViewportConstrained;
1328
1329     if (m_maskLayer) {
1330         auto& maskLayerCA = downcast<GraphicsLayerCA>(*m_maskLayer);
1331         if (maskLayerCA.recursiveVisibleRectChangeRequiresFlush(childCommitState, localState))
1332             return true;
1333     }
1334
1335     for (const auto& layer : children()) {
1336         const auto& currentChild = downcast<GraphicsLayerCA>(layer.get());
1337         if (currentChild.recursiveVisibleRectChangeRequiresFlush(childCommitState, localState))
1338             return true;
1339     }
1340
1341     if (m_replicaLayer)
1342         if (downcast<GraphicsLayerCA>(*m_replicaLayer).recursiveVisibleRectChangeRequiresFlush(childCommitState, localState))
1343             return true;
1344     
1345     return false;
1346 }
1347
1348 bool GraphicsLayerCA::visibleRectChangeRequiresFlush(const FloatRect& clipRect) const
1349 {
1350     TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(clipRect));
1351     CommitState commitState;
1352     return recursiveVisibleRectChangeRequiresFlush(commitState, state);
1353 }
1354
1355 TiledBacking* GraphicsLayerCA::tiledBacking() const
1356 {
1357     return m_layer->tiledBacking();
1358 }
1359
1360 TransformationMatrix GraphicsLayerCA::layerTransform(const FloatPoint& position, const TransformationMatrix* customTransform) const
1361 {
1362     TransformationMatrix transform;
1363     transform.translate(position.x(), position.y());
1364
1365     TransformationMatrix currentTransform;
1366     if (customTransform)
1367         currentTransform = *customTransform;
1368     else if (m_transform)
1369         currentTransform = *m_transform;
1370     
1371     if (!currentTransform.isIdentity()) {
1372         FloatPoint3D absoluteAnchorPoint(anchorPoint());
1373         absoluteAnchorPoint.scale(size().width(), size().height(), 1);
1374         transform.translate3d(absoluteAnchorPoint.x(), absoluteAnchorPoint.y(), absoluteAnchorPoint.z());
1375         transform.multiply(currentTransform);
1376         transform.translate3d(-absoluteAnchorPoint.x(), -absoluteAnchorPoint.y(), -absoluteAnchorPoint.z());
1377     }
1378
1379     if (GraphicsLayer* parentLayer = parent()) {
1380         if (parentLayer->hasNonIdentityChildrenTransform()) {
1381             FloatPoint3D parentAnchorPoint(parentLayer->anchorPoint());
1382             parentAnchorPoint.scale(parentLayer->size().width(), parentLayer->size().height(), 1);
1383
1384             transform.translateRight3d(-parentAnchorPoint.x(), -parentAnchorPoint.y(), -parentAnchorPoint.z());
1385             transform = parentLayer->childrenTransform() * transform;
1386             transform.translateRight3d(parentAnchorPoint.x(), parentAnchorPoint.y(), parentAnchorPoint.z());
1387         }
1388     }
1389     
1390     return transform;
1391 }
1392
1393 GraphicsLayerCA::VisibleAndCoverageRects GraphicsLayerCA::computeVisibleAndCoverageRect(TransformState& state, bool preserves3D, ComputeVisibleRectFlags flags) const
1394 {
1395     FloatPoint position = approximatePosition();
1396     client().customPositionForVisibleRectComputation(this, position);
1397
1398     TransformationMatrix layerTransform;
1399     TransformationMatrix currentTransform;
1400     if ((flags & RespectAnimatingTransforms) && client().getCurrentTransform(this, currentTransform))
1401         layerTransform = this->layerTransform(position, &currentTransform);
1402     else
1403         layerTransform = this->layerTransform(position);
1404
1405     bool applyWasClamped;
1406     TransformState::TransformAccumulation accumulation = preserves3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform;
1407     state.applyTransform(layerTransform, accumulation, &applyWasClamped);
1408
1409     bool mapWasClamped;
1410     FloatRect clipRectForChildren = state.mappedQuad(&mapWasClamped).boundingBox();
1411     FloatPoint boundsOrigin = m_boundsOrigin;
1412 #if PLATFORM(IOS_FAMILY)
1413     // In WK1, UIKit may be changing layer bounds behind our back in overflow-scroll layers, so use the layer's origin.
1414     if (m_layer->isPlatformCALayerCocoa())
1415         boundsOrigin = m_layer->bounds().location();
1416 #endif
1417     clipRectForChildren.move(boundsOrigin.x(), boundsOrigin.y());
1418     
1419     FloatRect clipRectForSelf(boundsOrigin, m_size);
1420     if (!applyWasClamped && !mapWasClamped)
1421         clipRectForSelf.intersect(clipRectForChildren);
1422
1423     if (masksToBounds()) {
1424         ASSERT(accumulation == TransformState::FlattenTransform);
1425         // Flatten, and replace the quad in the TransformState with one that is clipped to this layer's bounds.
1426         state.flatten();
1427         state.setQuad(clipRectForSelf);
1428         if (state.isMappingSecondaryQuad()) {
1429             FloatQuad secondaryQuad(clipRectForSelf);
1430             state.setSecondaryQuad(&secondaryQuad);
1431         }
1432     }
1433
1434     FloatRect coverageRect = clipRectForSelf;
1435     Optional<FloatQuad> quad = state.mappedSecondaryQuad(&mapWasClamped);
1436     if (quad && !mapWasClamped && !applyWasClamped)
1437         coverageRect = (*quad).boundingBox();
1438
1439     return { clipRectForSelf, coverageRect, currentTransform };
1440 }
1441
1442 bool GraphicsLayerCA::adjustCoverageRect(VisibleAndCoverageRects& rects, const FloatRect& oldVisibleRect) const
1443 {
1444     FloatRect coverageRect = rects.coverageRect;
1445
1446     switch (type()) {
1447     case Type::PageTiledBacking:
1448         coverageRect = tiledBacking()->adjustTileCoverageRectForScrolling(coverageRect, size(), oldVisibleRect, rects.visibleRect, pageScaleFactor() * deviceScaleFactor());
1449         break;
1450     case Type::ScrolledContents:
1451         if (m_layer->usesTiledBackingLayer())
1452             coverageRect = tiledBacking()->adjustTileCoverageRectForScrolling(coverageRect, size(), oldVisibleRect, rects.visibleRect, pageScaleFactor() * deviceScaleFactor());
1453         else {
1454             // Even if we don't have tiled backing, we want to expand coverage so that contained layers get attached backing store.
1455             coverageRect = adjustCoverageRectForMovement(coverageRect, oldVisibleRect, rects.visibleRect);
1456         }
1457         break;
1458     case Type::Normal:
1459         if (m_layer->usesTiledBackingLayer())
1460             coverageRect = tiledBacking()->adjustTileCoverageRect(coverageRect, oldVisibleRect, rects.visibleRect, size() != m_sizeAtLastCoverageRectUpdate);
1461         break;
1462     default:
1463         break;
1464     }
1465     
1466     if (rects.coverageRect == coverageRect)
1467         return false;
1468
1469     rects.coverageRect = coverageRect;
1470     return true;
1471 }
1472
1473 void GraphicsLayerCA::setVisibleAndCoverageRects(const VisibleAndCoverageRects& rects, bool isViewportConstrained)
1474 {
1475     bool visibleRectChanged = rects.visibleRect != m_visibleRect;
1476     bool coverageRectChanged = rects.coverageRect != m_coverageRect;
1477     if (!visibleRectChanged && !coverageRectChanged && !animationExtent())
1478         return;
1479
1480     auto bounds = FloatRect(m_boundsOrigin, size());
1481     if (auto extent = animationExtent()) {
1482         // Adjust the animation extent to match the current animation position.
1483         bounds = rects.animatingTransform.inverse().valueOr(TransformationMatrix()).mapRect(*extent);
1484     }
1485
1486     // FIXME: we need to take reflections into account when determining whether this layer intersects the coverage rect.
1487     bool intersectsCoverageRect = isViewportConstrained || rects.coverageRect.intersects(bounds);
1488     if (intersectsCoverageRect != m_intersectsCoverageRect) {
1489         addUncommittedChanges(CoverageRectChanged);
1490         m_intersectsCoverageRect = intersectsCoverageRect;
1491     }
1492
1493     if (visibleRectChanged) {
1494         addUncommittedChanges(CoverageRectChanged);
1495         m_visibleRect = rects.visibleRect;
1496     }
1497
1498     if (coverageRectChanged) {
1499         addUncommittedChanges(CoverageRectChanged);
1500         m_coverageRect = rects.coverageRect;
1501     }
1502 }
1503
1504 bool GraphicsLayerCA::needsCommit(const CommitState& commitState)
1505 {
1506     if (commitState.ancestorHadChanges)
1507         return true;
1508     if (m_uncommittedChanges)
1509         return true;
1510     if (hasDescendantsWithUncommittedChanges())
1511         return true;
1512     // Accelerated transforms move the underlying layers without GraphicsLayers getting invalidated.
1513     if (isRunningTransformAnimation())
1514         return true;
1515     if (hasDescendantsWithRunningTransformAnimations())
1516         return true;
1517
1518     return false;
1519 }
1520
1521 // rootRelativeTransformForScaling is a transform from the root, but for layers with transform animations, it cherry-picked the state of the
1522 // animation that contributes maximally to the scale (on every layer with animations down the hierarchy).
1523 void GraphicsLayerCA::recursiveCommitChanges(CommitState& commitState, const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
1524 {
1525     if (!needsCommit(commitState))
1526         return;
1527
1528     TransformState localState = state;
1529     CommitState childCommitState = commitState;
1530
1531     bool affectedByTransformAnimation = commitState.ancestorHasTransformAnimation;
1532
1533     bool accumulateTransform = accumulatesTransform(*this);
1534     VisibleAndCoverageRects rects = computeVisibleAndCoverageRect(localState, accumulateTransform);
1535     if (adjustCoverageRect(rects, m_visibleRect)) {
1536         if (state.isMappingSecondaryQuad()) {
1537             FloatQuad secondaryQuad(rects.coverageRect);
1538             localState.setLastPlanarSecondaryQuad(&secondaryQuad);
1539         }
1540     }
1541     setVisibleAndCoverageRects(rects, m_isViewportConstrained || commitState.ancestorIsViewportConstrained);
1542
1543     if (commitState.ancestorStartedOrEndedTransformAnimation)
1544         addUncommittedChanges(CoverageRectChanged);
1545
1546 #ifdef VISIBLE_TILE_WASH
1547     // Use having a transform as a key to making the tile wash layer. If every layer gets a wash,
1548     // they start to obscure useful information.
1549     if ((!m_transform.isIdentity() || tiledBacking()) && !m_visibleTileWashLayer) {
1550         static NeverDestroyed<Color> washFillColor(255, 0, 0, 50);
1551         static NeverDestroyed<Color> washBorderColor(255, 0, 0, 100);
1552         
1553         m_visibleTileWashLayer = createPlatformCALayer(PlatformCALayer::LayerTypeLayer, this);
1554         String name = makeString("Visible Tile Wash Layer 0x", hex(reinterpret_cast<uintptr_t>(m_visibleTileWashLayer->platformLayer()), Lowercase));
1555         m_visibleTileWashLayer->setName(name);
1556         m_visibleTileWashLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
1557         m_visibleTileWashLayer->setBorderColor(washBorderColor);
1558         m_visibleTileWashLayer->setBorderWidth(8);
1559         m_visibleTileWashLayer->setBackgroundColor(washFillColor);
1560         noteSublayersChanged(DontScheduleFlush);
1561     }
1562
1563     if (m_visibleTileWashLayer) {
1564         m_visibleTileWashLayer->setPosition(m_visibleRect.location());
1565         m_visibleTileWashLayer->setBounds(FloatRect(FloatPoint(), m_visibleRect.size()));
1566     }
1567 #endif
1568
1569     bool hadChanges = m_uncommittedChanges;
1570
1571     // FIXME: This could be more fine-grained. Only some types of changes have impact on sublayers.
1572     if (!childCommitState.ancestorHadChanges)
1573         childCommitState.ancestorHadChanges = hadChanges;
1574
1575     if (appliesPageScale()) {
1576         pageScaleFactor = this->pageScaleFactor();
1577         affectedByPageScale = true;
1578     }
1579
1580     // Accumulate an offset from the ancestral pixel-aligned layer.
1581     FloatPoint baseRelativePosition = positionRelativeToBase;
1582     if (affectedByPageScale)
1583         baseRelativePosition += m_position;
1584
1585     bool wasRunningTransformAnimation = isRunningTransformAnimation();
1586     bool layerTypeChanged = false;
1587     
1588     commitLayerChangesBeforeSublayers(childCommitState, pageScaleFactor, baseRelativePosition, layerTypeChanged);
1589
1590     bool nowRunningTransformAnimation = wasRunningTransformAnimation;
1591     if (m_uncommittedChanges & AnimationChanged)
1592         nowRunningTransformAnimation = isRunningTransformAnimation();
1593
1594     if (wasRunningTransformAnimation != nowRunningTransformAnimation)
1595         childCommitState.ancestorStartedOrEndedTransformAnimation = true;
1596
1597     if (nowRunningTransformAnimation) {
1598         childCommitState.ancestorHasTransformAnimation = true;
1599         if (m_intersectsCoverageRect || !animationExtent())
1600             childCommitState.ancestorWithTransformAnimationIntersectsCoverageRect = true;
1601         affectedByTransformAnimation = true;
1602     }
1603     
1604     childCommitState.ancestorIsViewportConstrained |= m_isViewportConstrained;
1605
1606     if (GraphicsLayerCA* maskLayer = downcast<GraphicsLayerCA>(m_maskLayer.get())) {
1607         maskLayer->setVisibleAndCoverageRects(rects, m_isViewportConstrained || commitState.ancestorIsViewportConstrained);
1608         maskLayer->commitLayerChangesBeforeSublayers(childCommitState, pageScaleFactor, baseRelativePosition, layerTypeChanged);
1609     }
1610
1611     bool hasDescendantsWithRunningTransformAnimations = false;
1612     
1613     for (auto& layer : children()) {
1614         auto& currentChild = downcast<GraphicsLayerCA>(layer.get());
1615         currentChild.recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
1616
1617         if (currentChild.isRunningTransformAnimation() || currentChild.hasDescendantsWithRunningTransformAnimations())
1618             hasDescendantsWithRunningTransformAnimations = true;
1619     }
1620
1621     commitState.totalBackdropFilterArea = childCommitState.totalBackdropFilterArea;
1622
1623     if (GraphicsLayerCA* replicaLayer = downcast<GraphicsLayerCA>(m_replicaLayer.get()))
1624         replicaLayer->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
1625
1626     if (GraphicsLayerCA* maskLayer = downcast<GraphicsLayerCA>(m_maskLayer.get()))
1627         maskLayer->commitLayerChangesAfterSublayers(childCommitState);
1628
1629     setHasDescendantsWithUncommittedChanges(false);
1630     setHasDescendantsWithRunningTransformAnimations(hasDescendantsWithRunningTransformAnimations);
1631
1632     bool hadDirtyRects = m_uncommittedChanges & DirtyRectsChanged;
1633     commitLayerChangesAfterSublayers(childCommitState);
1634
1635     if (affectedByTransformAnimation && m_layer->layerType() == PlatformCALayer::LayerTypeTiledBackingLayer)
1636         client().notifyFlushBeforeDisplayRefresh(this);
1637
1638     if (layerTypeChanged)
1639         client().didChangePlatformLayerForLayer(this);
1640
1641     if (usesDisplayListDrawing() && m_drawsContent && (!m_hasEverPainted || hadDirtyRects)) {
1642         TraceScope tracingScope(DisplayListRecordStart, DisplayListRecordEnd);
1643
1644         m_displayList = std::make_unique<DisplayList::DisplayList>();
1645         
1646         FloatRect initialClip(boundsOrigin(), size());
1647
1648         GraphicsContext context([&](GraphicsContext& context) {
1649             return std::make_unique<DisplayList::Recorder>(context, *m_displayList, GraphicsContextState(), initialClip, AffineTransform());
1650         });
1651         paintGraphicsLayerContents(context, FloatRect(FloatPoint(), size()));
1652     }
1653 }
1654
1655 void GraphicsLayerCA::platformCALayerCustomSublayersChanged(PlatformCALayer*)
1656 {
1657     noteLayerPropertyChanged(ChildrenChanged, m_isCommittingChanges ? DontScheduleFlush : ScheduleFlush);
1658 }
1659
1660 bool GraphicsLayerCA::platformCALayerShowRepaintCounter(PlatformCALayer* platformLayer) const
1661 {
1662     // The repaint counters are painted into the TileController tiles (which have no corresponding platform layer),
1663     // so we don't want to overpaint the repaint counter when called with the TileController's own layer.
1664     if (isPageTiledBackingLayer() && platformLayer)
1665         return false;
1666
1667     return isShowingRepaintCounter();
1668 }
1669
1670 void GraphicsLayerCA::platformCALayerPaintContents(PlatformCALayer*, GraphicsContext& context, const FloatRect& clip, GraphicsLayerPaintBehavior layerPaintBehavior)
1671 {
1672     m_hasEverPainted = true;
1673     if (m_displayList) {
1674         DisplayList::Replayer replayer(context, *m_displayList);
1675         
1676         if (UNLIKELY(isTrackingDisplayListReplay())) {
1677             auto replayList = replayer.replay(clip, isTrackingDisplayListReplay());
1678             layerDisplayListMap().add(this, std::pair<FloatRect, std::unique_ptr<DisplayList::DisplayList>>(clip, WTFMove(replayList)));
1679         } else
1680             replayer.replay(clip);
1681
1682         return;
1683     }
1684
1685     TraceScope tracingScope(PaintLayerStart, PaintLayerEnd);
1686     paintGraphicsLayerContents(context, clip, layerPaintBehavior);
1687 }
1688
1689 void GraphicsLayerCA::platformCALayerSetNeedsToRevalidateTiles()
1690 {
1691     noteLayerPropertyChanged(TilingAreaChanged, m_isCommittingChanges ? DontScheduleFlush : ScheduleFlush);
1692 }
1693
1694 float GraphicsLayerCA::platformCALayerDeviceScaleFactor() const
1695 {
1696     return deviceScaleFactor();
1697 }
1698
1699 float GraphicsLayerCA::platformCALayerContentsScaleMultiplierForNewTiles(PlatformCALayer*) const
1700 {
1701     return client().contentsScaleMultiplierForNewTiles(this);
1702 }
1703
1704 bool GraphicsLayerCA::platformCALayerShouldAggressivelyRetainTiles(PlatformCALayer*) const
1705 {
1706     return client().shouldAggressivelyRetainTiles(this);
1707 }
1708
1709 bool GraphicsLayerCA::platformCALayerShouldTemporarilyRetainTileCohorts(PlatformCALayer*) const
1710 {
1711     return client().shouldTemporarilyRetainTileCohorts(this);
1712 }
1713
1714 bool GraphicsLayerCA::platformCALayerUseGiantTiles() const
1715 {
1716     return client().useGiantTiles();
1717 }
1718
1719 void GraphicsLayerCA::platformCALayerLogFilledVisibleFreshTile(unsigned blankPixelCount)
1720 {
1721     client().logFilledVisibleFreshTile(blankPixelCount);
1722 }
1723
1724 static PlatformCALayer::LayerType layerTypeForCustomBackdropAppearance(GraphicsLayer::CustomAppearance appearance)
1725 {
1726     return appearance == GraphicsLayer::CustomAppearance::LightBackdrop ? PlatformCALayer::LayerTypeLightSystemBackdropLayer : PlatformCALayer::LayerTypeDarkSystemBackdropLayer;
1727 }
1728
1729 static bool isCustomBackdropLayerType(PlatformCALayer::LayerType layerType)
1730 {
1731     return layerType == PlatformCALayer::LayerTypeLightSystemBackdropLayer || layerType == PlatformCALayer::LayerTypeDarkSystemBackdropLayer;
1732 }
1733
1734 void GraphicsLayerCA::commitLayerChangesBeforeSublayers(CommitState& commitState, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool& layerChanged)
1735 {
1736     SetForScope<bool> committingChangesChange(m_isCommittingChanges, true);
1737
1738     ++commitState.treeDepth;
1739     if (m_structuralLayer)
1740         ++commitState.treeDepth;
1741
1742     if (!m_uncommittedChanges) {
1743         // Ensure that we cap layer depth in commitLayerChangesAfterSublayers().
1744         if (commitState.treeDepth > cMaxLayerTreeDepth)
1745             addUncommittedChanges(ChildrenChanged);
1746     }
1747
1748     bool needTiledLayer = requiresTiledLayer(pageScaleFactor);
1749     bool needBackdropLayerType = (customAppearance() == CustomAppearance::LightBackdrop || customAppearance() == CustomAppearance::DarkBackdrop);
1750
1751     PlatformCALayer::LayerType currentLayerType = m_layer->layerType();
1752     PlatformCALayer::LayerType neededLayerType = currentLayerType;
1753
1754     if (needBackdropLayerType)
1755         neededLayerType = layerTypeForCustomBackdropAppearance(customAppearance());
1756     else if (needTiledLayer)
1757         neededLayerType = PlatformCALayer::LayerTypeTiledBackingLayer;
1758     else if (currentLayerType == PlatformCALayer::LayerTypeTiledBackingLayer || isCustomBackdropLayerType(m_layer->layerType()))
1759         neededLayerType = PlatformCALayer::LayerTypeWebLayer;
1760
1761     if (neededLayerType != m_layer->layerType()) {
1762         changeLayerTypeTo(neededLayerType);
1763         layerChanged = true;
1764     }
1765
1766     // Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to
1767     if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged | BackdropFiltersChanged)) {
1768         if (updateStructuralLayer())
1769             layerChanged = true;
1770     }
1771
1772     if (m_uncommittedChanges & GeometryChanged)
1773         updateGeometry(pageScaleFactor, positionRelativeToBase);
1774
1775     if (m_uncommittedChanges & DrawsContentChanged)
1776         updateDrawsContent();
1777
1778     if (m_uncommittedChanges & NameChanged)
1779         updateNames();
1780
1781     if (m_uncommittedChanges & ContentsImageChanged) // Needs to happen before ChildrenChanged
1782         updateContentsImage();
1783         
1784     if (m_uncommittedChanges & ContentsPlatformLayerChanged) // Needs to happen before ChildrenChanged
1785         updateContentsPlatformLayer();
1786
1787     if (m_uncommittedChanges & ContentsColorLayerChanged) // Needs to happen before ChildrenChanged
1788         updateContentsColorLayer();
1789     
1790     if (m_uncommittedChanges & BackgroundColorChanged)
1791         updateBackgroundColor();
1792
1793     if (m_uncommittedChanges & TransformChanged)
1794         updateTransform();
1795
1796     if (m_uncommittedChanges & ChildrenTransformChanged)
1797         updateChildrenTransform();
1798     
1799     if (m_uncommittedChanges & MasksToBoundsChanged)
1800         updateMasksToBounds();
1801     
1802     if (m_uncommittedChanges & ContentsVisibilityChanged)
1803         updateContentsVisibility();
1804
1805     if (m_uncommittedChanges & UserInteractionEnabledChanged)
1806         updateUserInteractionEnabled();
1807
1808     // Note that contentsScale can affect whether the layer can be opaque.
1809     if (m_uncommittedChanges & ContentsOpaqueChanged)
1810         updateContentsOpaque(pageScaleFactor);
1811
1812     if (m_uncommittedChanges & BackfaceVisibilityChanged)
1813         updateBackfaceVisibility();
1814
1815     if (m_uncommittedChanges & OpacityChanged)
1816         updateOpacityOnLayer();
1817
1818     if (m_uncommittedChanges & FiltersChanged)
1819         updateFilters();
1820
1821     // If there are backdrop filters, we need to always check the resource usage
1822     // because something up the tree may have changed its usage.
1823     if (m_uncommittedChanges & BackdropFiltersChanged || needsBackdrop())
1824         updateBackdropFilters(commitState);
1825
1826     if (m_uncommittedChanges & BackdropFiltersRectChanged)
1827         updateBackdropFiltersRect();
1828
1829 #if ENABLE(CSS_COMPOSITING)
1830     if (m_uncommittedChanges & BlendModeChanged)
1831         updateBlendMode();
1832 #endif
1833
1834     if (m_uncommittedChanges & ShapeChanged)
1835         updateShape();
1836
1837     if (m_uncommittedChanges & WindRuleChanged)
1838         updateWindRule();
1839
1840     if (m_uncommittedChanges & AnimationChanged)
1841         updateAnimations();
1842
1843     // Updating the contents scale can cause parts of the layer to be invalidated,
1844     // so make sure to update the contents scale before updating the dirty rects.
1845     if (m_uncommittedChanges & ContentsScaleChanged)
1846         updateContentsScale(pageScaleFactor);
1847
1848     if (m_uncommittedChanges & CoverageRectChanged)
1849         updateCoverage(commitState);
1850
1851     if (m_uncommittedChanges & AcceleratesDrawingChanged) // Needs to happen before TilingAreaChanged.
1852         updateAcceleratesDrawing();
1853
1854     if (m_uncommittedChanges & TilingAreaChanged) // Needs to happen after CoverageRectChanged, ContentsScaleChanged
1855         updateTiles();
1856
1857     if (m_uncommittedChanges & DirtyRectsChanged)
1858         repaintLayerDirtyRects();
1859     
1860     if (m_uncommittedChanges & ContentsRectsChanged) // Needs to happen before ChildrenChanged
1861         updateContentsRects();
1862
1863     if (m_uncommittedChanges & MasksToBoundsRectChanged) // Needs to happen before ChildrenChanged
1864         updateMasksToBoundsRect();
1865
1866     if (m_uncommittedChanges & EventRegionChanged)
1867         updateEventRegion();
1868
1869     if (m_uncommittedChanges & MaskLayerChanged) {
1870         updateMaskLayer();
1871         // If the mask layer becomes tiled it can set this flag again. Clear the flag so that
1872         // commitLayerChangesAfterSublayers doesn't update the mask again in the normal case.
1873         m_uncommittedChanges &= ~MaskLayerChanged;
1874     }
1875
1876     if (m_uncommittedChanges & ContentsNeedsDisplay)
1877         updateContentsNeedsDisplay();
1878
1879     if (m_uncommittedChanges & SupportsSubpixelAntialiasedTextChanged)
1880         updateSupportsSubpixelAntialiasedText();
1881
1882     if (m_uncommittedChanges & DebugIndicatorsChanged)
1883         updateDebugIndicators();
1884
1885     if (m_uncommittedChanges & CustomAppearanceChanged)
1886         updateCustomAppearance();
1887
1888     if (m_uncommittedChanges & ChildrenChanged) {
1889         updateSublayerList();
1890         // Sublayers may set this flag again, so clear it to avoid always updating sublayers in commitLayerChangesAfterSublayers().
1891         m_uncommittedChanges &= ~ChildrenChanged;
1892     }
1893
1894     // Ensure that we cap layer depth in commitLayerChangesAfterSublayers().
1895     if (commitState.treeDepth > cMaxLayerTreeDepth)
1896         addUncommittedChanges(ChildrenChanged);
1897 }
1898
1899 void GraphicsLayerCA::commitLayerChangesAfterSublayers(CommitState& commitState)
1900 {
1901     if (!m_uncommittedChanges)
1902         return;
1903
1904     SetForScope<bool> committingChangesChange(m_isCommittingChanges, true);
1905
1906     if (m_uncommittedChanges & MaskLayerChanged)
1907         updateMaskLayer();
1908
1909     if (m_uncommittedChanges & ChildrenChanged)
1910         updateSublayerList(commitState.treeDepth > cMaxLayerTreeDepth);
1911
1912     if (m_uncommittedChanges & ReplicatedLayerChanged)
1913         updateReplicatedLayers();
1914
1915     m_uncommittedChanges = NoChange;
1916 }
1917
1918 void GraphicsLayerCA::updateNames()
1919 {
1920     switch (structuralLayerPurpose()) {
1921     case StructuralLayerForPreserves3D:
1922         m_structuralLayer->setName("preserve-3d: " + name());
1923         break;
1924     case StructuralLayerForReplicaFlattening:
1925         m_structuralLayer->setName("replica flattening: " + name());
1926         break;
1927     case StructuralLayerForBackdrop:
1928         m_structuralLayer->setName("backdrop hosting: " + name());
1929         break;
1930     case NoStructuralLayer:
1931         break;
1932     }
1933     m_layer->setName(name());
1934 }
1935
1936 void GraphicsLayerCA::updateSublayerList(bool maxLayerDepthReached)
1937 {
1938     if (maxLayerDepthReached) {
1939         m_layer->setSublayers(PlatformCALayerList());
1940         return;
1941     }
1942     
1943     const PlatformCALayerList* customSublayers = m_layer->customSublayers();
1944
1945     PlatformCALayerList structuralLayerChildren;
1946     PlatformCALayerList primaryLayerChildren;
1947
1948     PlatformCALayerList& childListForSublayers = m_structuralLayer ? structuralLayerChildren : primaryLayerChildren;
1949
1950     if (customSublayers)
1951         primaryLayerChildren.appendVector(*customSublayers);
1952
1953     if (m_structuralLayer) {
1954         if (m_backdropLayer)
1955             structuralLayerChildren.append(m_backdropLayer);
1956
1957         if (m_replicaLayer)
1958             structuralLayerChildren.append(downcast<GraphicsLayerCA>(*m_replicaLayer).primaryLayer());
1959     
1960         structuralLayerChildren.append(m_layer);
1961     }
1962
1963     if (m_contentsLayer && m_contentsVisible) {
1964         // FIXME: add the contents layer in the correct order with negative z-order children.
1965         // This does not cause visible rendering issues because currently contents layers are only used
1966         // for replaced elements that don't have children.
1967         primaryLayerChildren.append(m_contentsClippingLayer ? m_contentsClippingLayer : m_contentsLayer);
1968     }
1969     
1970     for (const auto& layer : children()) {
1971         const auto& currentChild = downcast<GraphicsLayerCA>(layer.get());
1972         PlatformCALayer* childLayer = currentChild.layerForSuperlayer();
1973         childListForSublayers.append(childLayer);
1974     }
1975
1976 #ifdef VISIBLE_TILE_WASH
1977     if (m_visibleTileWashLayer)
1978         childListForSublayers.append(m_visibleTileWashLayer);
1979 #endif
1980
1981     if (m_structuralLayer)
1982         m_structuralLayer->setSublayers(structuralLayerChildren);
1983     
1984     m_layer->setSublayers(primaryLayerChildren);
1985 }
1986
1987 void GraphicsLayerCA::updateGeometry(float pageScaleFactor, const FloatPoint& positionRelativeToBase)
1988 {
1989     FloatPoint scaledPosition = m_position;
1990     FloatPoint3D scaledAnchorPoint = m_anchorPoint;
1991     FloatSize scaledSize = m_size;
1992     FloatSize pixelAlignmentOffset;
1993
1994     // FIXME: figure out if we really need to pixel align the graphics layer here.
1995     if (client().needsPixelAligment() && !WTF::isIntegral(pageScaleFactor) && m_drawsContent && !m_masksToBounds)
1996         computePixelAlignment(pageScaleFactor, positionRelativeToBase, scaledPosition, scaledAnchorPoint, pixelAlignmentOffset);
1997
1998     // Update position.
1999     // Position is offset on the layer by the layer anchor point.
2000     FloatPoint adjustedPosition(scaledPosition.x() + scaledAnchorPoint.x() * scaledSize.width(), scaledPosition.y() + scaledAnchorPoint.y() * scaledSize.height());
2001
2002     if (m_structuralLayer) {
2003         FloatPoint layerPosition(m_position.x() + m_anchorPoint.x() * m_size.width(), m_position.y() + m_anchorPoint.y() * m_size.height());
2004         FloatRect layerBounds(m_boundsOrigin, m_size);
2005
2006         m_structuralLayer->setPosition(layerPosition);
2007         m_structuralLayer->setBounds(layerBounds);
2008         m_structuralLayer->setAnchorPoint(m_anchorPoint);
2009
2010         if (m_layerClones) {
2011             for (auto& clone : m_layerClones->structuralLayerClones) {
2012                 PlatformCALayer* cloneLayer = clone.value.get();
2013                 FloatPoint clonePosition = layerPosition;
2014
2015                 if (m_replicaLayer && isReplicatedRootClone(clone.key)) {
2016                     // Maintain the special-case position for the root of a clone subtree,
2017                     // which we set up in replicatedLayerRoot().
2018                     clonePosition = positionForCloneRootLayer();
2019                 }
2020
2021                 cloneLayer->setPosition(clonePosition);
2022                 cloneLayer->setBounds(layerBounds);
2023                 cloneLayer->setAnchorPoint(m_anchorPoint);
2024             }
2025         }
2026
2027         // If we have a structural layer, we just use 0.5, 0.5 for the anchor point of the main layer.
2028         scaledAnchorPoint = FloatPoint(0.5f, 0.5f);
2029         adjustedPosition = FloatPoint(scaledAnchorPoint.x() * scaledSize.width() - pixelAlignmentOffset.width(), scaledAnchorPoint.y() * scaledSize.height() - pixelAlignmentOffset.height());
2030     }
2031
2032     m_pixelAlignmentOffset = pixelAlignmentOffset;
2033
2034     // Push the layer to device pixel boundary (setPosition()), but move the content back to its original position (setBounds())
2035     m_layer->setPosition(adjustedPosition);
2036     FloatRect adjustedBounds = FloatRect(FloatPoint(m_boundsOrigin - pixelAlignmentOffset), m_size);
2037     m_layer->setBounds(adjustedBounds);
2038     m_layer->setAnchorPoint(scaledAnchorPoint);
2039
2040     if (m_layerClones) {
2041         for (auto& clone : m_layerClones->primaryLayerClones) {
2042             PlatformCALayer* cloneLayer = clone.value.get();
2043             FloatPoint clonePosition = adjustedPosition;
2044
2045             if (!m_structuralLayer && m_replicaLayer && isReplicatedRootClone(clone.key)) {
2046                 // Maintain the special-case position for the root of a clone subtree,
2047                 // which we set up in replicatedLayerRoot().
2048                 clonePosition = positionForCloneRootLayer();
2049             }
2050
2051             cloneLayer->setPosition(clonePosition);
2052             cloneLayer->setBounds(adjustedBounds);
2053             cloneLayer->setAnchorPoint(scaledAnchorPoint);
2054         }
2055     }
2056 }
2057
2058 void GraphicsLayerCA::updateTransform()
2059 {
2060     primaryLayer()->setTransform(transform());
2061
2062     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2063         for (auto& clone : *layerCloneMap) {
2064             PlatformCALayer* currLayer = clone.value.get();
2065             if (m_replicaLayer && isReplicatedRootClone(clone.key)) {
2066                 // Maintain the special-case transform for the root of a clone subtree,
2067                 // which we set up in replicatedLayerRoot().
2068                 currLayer->setTransform(TransformationMatrix());
2069             } else
2070                 currLayer->setTransform(transform());
2071         }
2072     }
2073 }
2074
2075 void GraphicsLayerCA::updateChildrenTransform()
2076 {
2077     primaryLayer()->setSublayerTransform(childrenTransform());
2078
2079     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2080         for (auto& layer : layerCloneMap->values())
2081             layer->setSublayerTransform(childrenTransform());
2082     }
2083 }
2084
2085 void GraphicsLayerCA::updateMasksToBounds()
2086 {
2087     m_layer->setMasksToBounds(m_masksToBounds);
2088
2089     if (m_layerClones) {
2090         for (auto& layer : m_layerClones->primaryLayerClones.values())
2091             layer->setMasksToBounds(m_masksToBounds);
2092     }
2093 }
2094
2095 void GraphicsLayerCA::updateContentsVisibility()
2096 {
2097     // Note that m_contentsVisible also affects whether m_contentsLayer is parented.
2098     if (m_contentsVisible) {
2099         if (m_drawsContent)
2100             m_layer->setNeedsDisplay();
2101
2102         if (m_backdropLayer)
2103             m_backdropLayer->setHidden(false);
2104     } else {
2105         m_layer->setContents(nullptr);
2106
2107         if (m_layerClones) {
2108             for (auto& layer : m_layerClones->primaryLayerClones.values())
2109                 layer->setContents(nullptr);
2110         }
2111
2112         if (m_backdropLayer)
2113             m_backdropLayer->setHidden(true);
2114     }
2115
2116     m_layer->setContentsHidden(!m_contentsVisible);
2117 }
2118
2119 void GraphicsLayerCA::updateUserInteractionEnabled()
2120 {
2121     m_layer->setUserInteractionEnabled(m_userInteractionEnabled);
2122 }
2123
2124 void GraphicsLayerCA::updateContentsOpaque(float pageScaleFactor)
2125 {
2126     bool contentsOpaque = m_contentsOpaque;
2127     if (contentsOpaque) {
2128         float contentsScale = pageScaleFactor * deviceScaleFactor();
2129         if (!WTF::isIntegral(contentsScale) && !client().paintsOpaquelyAtNonIntegralScales(this))
2130             contentsOpaque = false;
2131     }
2132     
2133     m_layer->setOpaque(contentsOpaque);
2134
2135     if (m_layerClones) {
2136         for (auto& layer : m_layerClones->primaryLayerClones.values())
2137             layer->setOpaque(contentsOpaque);
2138     }
2139 }
2140
2141 void GraphicsLayerCA::updateBackfaceVisibility()
2142 {
2143     if (m_structuralLayer && structuralLayerPurpose() == StructuralLayerForReplicaFlattening) {
2144         m_structuralLayer->setDoubleSided(m_backfaceVisibility);
2145
2146         if (m_layerClones) {
2147             for (auto& layer : m_layerClones->structuralLayerClones.values())
2148                 layer->setDoubleSided(m_backfaceVisibility);
2149         }
2150     }
2151
2152     m_layer->setDoubleSided(m_backfaceVisibility);
2153
2154     if (m_layerClones) {
2155         for (auto& layer : m_layerClones->primaryLayerClones.values())
2156             layer->setDoubleSided(m_backfaceVisibility);
2157     }
2158 }
2159
2160 void GraphicsLayerCA::updateFilters()
2161 {
2162     m_layer->setFilters(m_filters);
2163
2164     if (m_layerClones) {
2165         for (auto& clone : m_layerClones->primaryLayerClones) {
2166             if (m_replicaLayer && isReplicatedRootClone(clone.key))
2167                 continue;
2168
2169             clone.value->setFilters(m_filters);
2170         }
2171     }
2172 }
2173
2174 void GraphicsLayerCA::updateBackdropFilters(CommitState& commitState)
2175 {
2176     using CheckedUnsigned = Checked<unsigned, RecordOverflow>;
2177
2178     bool canHaveBackdropFilters = needsBackdrop();
2179
2180     if (canHaveBackdropFilters) {
2181         canHaveBackdropFilters = false;
2182         IntRect backdropFilterRect = enclosingIntRect(m_backdropFiltersRect.rect());
2183         if (backdropFilterRect.width() > 0 && backdropFilterRect.height() > 0) {
2184             CheckedUnsigned backdropFilterArea = CheckedUnsigned(backdropFilterRect.width()) * CheckedUnsigned(backdropFilterRect.height());
2185             if (!backdropFilterArea.hasOverflowed()) {
2186                 CheckedUnsigned newTotalBackdropFilterArea = CheckedUnsigned(commitState.totalBackdropFilterArea) + backdropFilterArea;
2187                 if (!newTotalBackdropFilterArea.hasOverflowed() && newTotalBackdropFilterArea.unsafeGet() <= cMaxTotalBackdropFilterArea) {
2188                     commitState.totalBackdropFilterArea = newTotalBackdropFilterArea.unsafeGet();
2189                     canHaveBackdropFilters = true;
2190                 }
2191             }
2192         }
2193     }
2194
2195     if (!canHaveBackdropFilters) {
2196         if (m_backdropLayer) {
2197             m_backdropLayer->removeFromSuperlayer();
2198             m_backdropLayer->setOwner(nullptr);
2199             m_backdropLayer = nullptr;
2200         }
2201         return;
2202     }
2203
2204     // If nothing actually changed, no need to touch the layer properties.
2205     if (!(m_uncommittedChanges & BackdropFiltersChanged))
2206         return;
2207
2208     bool madeLayer = !m_backdropLayer;
2209     if (!m_backdropLayer) {
2210         m_backdropLayer = createPlatformCALayer(PlatformCALayer::LayerTypeBackdropLayer, this);
2211         m_backdropLayer->setAnchorPoint(FloatPoint3D());
2212         m_backdropLayer->setMasksToBounds(true);
2213         m_backdropLayer->setName("backdrop");
2214     }
2215
2216     m_backdropLayer->setHidden(!m_contentsVisible);
2217     m_backdropLayer->setFilters(m_backdropFilters);
2218
2219     if (m_layerClones) {
2220         for (auto& clone : m_layerClones->backdropLayerClones) {
2221             PlatformCALayer* cloneLayer = clone.value.get();
2222             cloneLayer->setHidden(!m_contentsVisible);
2223             cloneLayer->setFilters(m_backdropFilters);
2224         }
2225     }
2226
2227     if (madeLayer) {
2228         updateBackdropFiltersRect();
2229         noteSublayersChanged(DontScheduleFlush);
2230     }
2231 }
2232
2233 void GraphicsLayerCA::updateBackdropFiltersRect()
2234 {
2235     if (!m_backdropLayer)
2236         return;
2237
2238     FloatRect contentBounds(0, 0, m_backdropFiltersRect.rect().width(), m_backdropFiltersRect.rect().height());
2239     m_backdropLayer->setBounds(contentBounds);
2240     m_backdropLayer->setPosition(m_backdropFiltersRect.rect().location());
2241
2242     updateClippingStrategy(*m_backdropLayer, m_backdropClippingLayer, m_backdropFiltersRect);
2243
2244     if (m_layerClones) {
2245         for (auto& clone : m_layerClones->backdropLayerClones) {
2246             PlatformCALayer* backdropCloneLayer = clone.value.get();
2247             backdropCloneLayer->setBounds(contentBounds);
2248             backdropCloneLayer->setPosition(m_backdropFiltersRect.rect().location());
2249
2250             CloneID cloneID = clone.key;
2251             RefPtr<PlatformCALayer> backdropClippingLayerClone = m_layerClones->backdropClippingLayerClones.get(cloneID);
2252
2253             bool hadBackdropClippingLayer = backdropClippingLayerClone;
2254             updateClippingStrategy(*backdropCloneLayer, backdropClippingLayerClone, m_backdropFiltersRect);
2255
2256             if (!backdropClippingLayerClone)
2257                 m_layerClones->backdropClippingLayerClones.remove(cloneID);
2258             else if (backdropClippingLayerClone && !hadBackdropClippingLayer)
2259                 m_layerClones->backdropClippingLayerClones.add(cloneID, backdropClippingLayerClone);
2260         }
2261     }
2262 }
2263
2264 #if ENABLE(CSS_COMPOSITING)
2265 void GraphicsLayerCA::updateBlendMode()
2266 {
2267     primaryLayer()->setBlendMode(m_blendMode);
2268
2269     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2270         for (auto& clone : *layerCloneMap) {
2271             if (m_replicaLayer && isReplicatedRootClone(clone.key))
2272                 continue;
2273             clone.value->setBlendMode(m_blendMode);
2274         }
2275     }
2276 }
2277 #endif
2278
2279 void GraphicsLayerCA::updateShape()
2280 {
2281     m_layer->setShapePath(m_shapeLayerPath);
2282
2283     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2284         for (auto& layer : layerCloneMap->values())
2285             layer->setShapePath(m_shapeLayerPath);
2286     }
2287 }
2288
2289 void GraphicsLayerCA::updateWindRule()
2290 {
2291     m_layer->setShapeWindRule(m_shapeLayerWindRule);
2292 }
2293
2294 bool GraphicsLayerCA::updateStructuralLayer()
2295 {
2296     return ensureStructuralLayer(structuralLayerPurpose());
2297 }
2298
2299 bool GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose)
2300 {
2301     const LayerChangeFlags structuralLayerChangeFlags = NameChanged
2302         | GeometryChanged
2303         | TransformChanged
2304         | ChildrenTransformChanged
2305         | ChildrenChanged
2306         | BackfaceVisibilityChanged
2307         | FiltersChanged
2308         | BackdropFiltersChanged
2309         | MaskLayerChanged
2310         | OpacityChanged;
2311
2312     bool structuralLayerChanged = false;
2313
2314     if (purpose == NoStructuralLayer) {
2315         if (m_structuralLayer) {
2316             // Replace the transformLayer in the parent with this layer.
2317             m_layer->removeFromSuperlayer();
2318  
2319             // If m_layer doesn't have a parent, it means it's the root layer and
2320             // is likely hosted by something that is not expecting to be changed
2321             ASSERT(m_structuralLayer->superlayer());
2322             m_structuralLayer->superlayer()->replaceSublayer(*m_structuralLayer, *m_layer);
2323
2324             moveAnimations(m_structuralLayer.get(), m_layer.get());
2325
2326             // Release the structural layer.
2327             m_structuralLayer = nullptr;
2328             structuralLayerChanged = true;
2329
2330             addUncommittedChanges(structuralLayerChangeFlags);
2331         }
2332         return structuralLayerChanged;
2333     }
2334
2335     if (purpose == StructuralLayerForPreserves3D) {
2336         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeTransformLayer)
2337             m_structuralLayer = nullptr;
2338         
2339         if (!m_structuralLayer) {
2340             m_structuralLayer = createPlatformCALayer(PlatformCALayer::LayerTypeTransformLayer, this);
2341             structuralLayerChanged = true;
2342         }
2343     } else {
2344         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeLayer)
2345             m_structuralLayer = nullptr;
2346
2347         if (!m_structuralLayer) {
2348             m_structuralLayer = createPlatformCALayer(PlatformCALayer::LayerTypeLayer, this);
2349             structuralLayerChanged = true;
2350         }
2351     }
2352     
2353     if (!structuralLayerChanged)
2354         return false;
2355     
2356     addUncommittedChanges(structuralLayerChangeFlags);
2357
2358     // We've changed the layer that our parent added to its sublayer list, so tell it to update
2359     // sublayers again in its commitLayerChangesAfterSublayers().
2360     downcast<GraphicsLayerCA>(*parent()).noteSublayersChanged(DontScheduleFlush);
2361
2362     // Set properties of m_layer to their default values, since these are expressed on on the structural layer.
2363     FloatPoint point(m_size.width() / 2.0f, m_size.height() / 2.0f);
2364     FloatPoint3D anchorPoint(0.5f, 0.5f, 0);
2365     m_layer->setPosition(point);
2366     m_layer->setAnchorPoint(anchorPoint);
2367     m_layer->setTransform(TransformationMatrix());
2368     m_layer->setOpacity(1);
2369     if (m_layerClones) {
2370         for (auto& layer : m_layerClones->primaryLayerClones.values()) {
2371             layer->setPosition(point);
2372             layer->setAnchorPoint(anchorPoint);
2373             layer->setTransform(TransformationMatrix());
2374             layer->setOpacity(1);
2375         }
2376     }
2377
2378     moveAnimations(m_layer.get(), m_structuralLayer.get());
2379     return true;
2380 }
2381
2382 GraphicsLayerCA::StructuralLayerPurpose GraphicsLayerCA::structuralLayerPurpose() const
2383 {
2384     if (preserves3D())
2385         return StructuralLayerForPreserves3D;
2386     
2387     if (isReplicated())
2388         return StructuralLayerForReplicaFlattening;
2389
2390     if (needsBackdrop())
2391         return StructuralLayerForBackdrop;
2392
2393     return NoStructuralLayer;
2394 }
2395
2396 void GraphicsLayerCA::updateDrawsContent()
2397 {
2398     if (m_drawsContent) {
2399         m_layer->setNeedsDisplay();
2400         m_hasEverPainted = false;
2401     } else {
2402         m_layer->setContents(nullptr);
2403         if (m_layerClones) {
2404             for (auto& layer : m_layerClones->primaryLayerClones.values())
2405                 layer->setContents(nullptr);
2406         }
2407     }
2408 }
2409
2410 void GraphicsLayerCA::updateCoverage(const CommitState& commitState)
2411 {
2412     // FIXME: Need to set coverage on clone layers too.
2413     if (TiledBacking* backing = tiledBacking()) {
2414         backing->setVisibleRect(m_visibleRect);
2415         backing->setCoverageRect(m_coverageRect);
2416     }
2417
2418     if (canDetachBackingStore()) {
2419         bool requiresBacking = m_intersectsCoverageRect
2420             || commitState.ancestorWithTransformAnimationIntersectsCoverageRect // FIXME: Compute backing exactly for descendants of animating layers.
2421             || (isRunningTransformAnimation() && !animationExtent()); // Create backing if we don't know the animation extent.
2422
2423 #if !LOG_DISABLED
2424         if (requiresBacking) {
2425             auto reasonForBacking = [&]() -> const char* {
2426                 if (m_intersectsCoverageRect)
2427                     return "intersectsCoverageRect";
2428                 
2429                 if (commitState.ancestorWithTransformAnimationIntersectsCoverageRect)
2430                     return "ancestor with transform";
2431                 
2432                 return "has transform animation with unknown extent";
2433             };
2434             LOG_WITH_STREAM(Layers, stream << "GraphicsLayerCA " << this << " id " << primaryLayerID() << " setBackingStoreAttached: " << requiresBacking << " (" << reasonForBacking() << ")");
2435         } else
2436             LOG_WITH_STREAM(Layers, stream << "GraphicsLayerCA " << this << " id " << primaryLayerID() << " setBackingStoreAttached: " << requiresBacking);
2437 #endif
2438
2439         m_layer->setBackingStoreAttached(requiresBacking);
2440         if (m_layerClones) {
2441             for (auto& layer : m_layerClones->primaryLayerClones.values())
2442                 layer->setBackingStoreAttached(requiresBacking);
2443         }
2444     }
2445
2446     m_sizeAtLastCoverageRectUpdate = m_size;
2447 }
2448
2449 void GraphicsLayerCA::updateAcceleratesDrawing()
2450 {
2451     m_layer->setAcceleratesDrawing(m_acceleratesDrawing);
2452 }
2453
2454 void GraphicsLayerCA::updateSupportsSubpixelAntialiasedText()
2455 {
2456     m_layer->setSupportsSubpixelAntialiasedText(m_supportsSubpixelAntialiasedText);
2457 }
2458
2459 static void setLayerDebugBorder(PlatformCALayer& layer, Color borderColor, float borderWidth)
2460 {
2461     layer.setBorderColor(borderColor);
2462     layer.setBorderWidth(borderColor.isValid() ? borderWidth : 0);
2463 }
2464
2465 static const float contentsLayerBorderWidth = 4;
2466 static Color contentsLayerDebugBorderColor(bool showingBorders)
2467 {
2468     return showingBorders ? Color(0, 0, 128, 180) : Color();
2469 }
2470
2471 static const float cloneLayerBorderWidth = 2;
2472 static Color cloneLayerDebugBorderColor(bool showingBorders)
2473 {
2474     return showingBorders ? Color(255, 122, 251) : Color();
2475 }
2476
2477 void GraphicsLayerCA::updateDebugIndicators()
2478 {
2479     Color borderColor;
2480     float width = 0;
2481
2482     bool showDebugBorders = isShowingDebugBorder();
2483     if (showDebugBorders)
2484         getDebugBorderInfo(borderColor, width);
2485
2486     // Paint repaint counter.
2487     m_layer->setNeedsDisplay();
2488
2489     setLayerDebugBorder(*m_layer, borderColor, width);
2490     if (m_contentsLayer)
2491         setLayerDebugBorder(*m_contentsLayer, contentsLayerDebugBorderColor(showDebugBorders), contentsLayerBorderWidth);
2492
2493     if (m_layerClones) {
2494         for (auto& layer : m_layerClones->primaryLayerClones.values())
2495             setLayerDebugBorder(*layer, borderColor, width);
2496
2497         Color cloneLayerBorderColor = cloneLayerDebugBorderColor(showDebugBorders);
2498         for (auto& layer : m_layerClones->structuralLayerClones.values())
2499             setLayerDebugBorder(*layer, cloneLayerBorderColor, cloneLayerBorderWidth);
2500
2501         Color contentsLayerBorderColor = contentsLayerDebugBorderColor(showDebugBorders);
2502         for (auto& layer : m_layerClones->contentsLayerClones.values())
2503             setLayerDebugBorder(*layer, contentsLayerBorderColor, contentsLayerBorderWidth);
2504     }
2505 }
2506
2507 void GraphicsLayerCA::updateTiles()
2508 {
2509     if (!m_layer->usesTiledBackingLayer())
2510         return;
2511
2512     tiledBacking()->revalidateTiles();
2513 }
2514
2515 void GraphicsLayerCA::updateBackgroundColor()
2516 {
2517     m_layer->setBackgroundColor(m_backgroundColor);
2518 }
2519
2520 void GraphicsLayerCA::updateContentsImage()
2521 {
2522     if (m_pendingContentsImage) {
2523         if (!m_contentsLayer.get()) {
2524             m_contentsLayer = createPlatformCALayer(PlatformCALayer::LayerTypeLayer, this);
2525 #if ENABLE(TREE_DEBUGGING)
2526             m_contentsLayer->setName(makeString("contents image ", m_contentsLayer->layerID()));
2527 #else
2528             m_contentsLayer->setName("contents image");
2529 #endif
2530             setupContentsLayer(m_contentsLayer.get());
2531             // m_contentsLayer will be parented by updateSublayerList
2532         }
2533
2534         // FIXME: maybe only do trilinear if the image is being scaled down,
2535         // but then what if the layer size changes?
2536         m_contentsLayer->setMinificationFilter(PlatformCALayer::Trilinear);
2537         m_contentsLayer->setContents(m_pendingContentsImage.get());
2538         m_pendingContentsImage = nullptr;
2539
2540         if (m_layerClones) {
2541             for (auto& layer : m_layerClones->contentsLayerClones.values())
2542                 layer->setContents(m_contentsLayer->contents());
2543         }
2544         
2545         updateContentsRects();
2546     } else {
2547         // No image.
2548         // m_contentsLayer will be removed via updateSublayerList.
2549         m_contentsLayer = nullptr;
2550     }
2551 }
2552
2553 void GraphicsLayerCA::updateContentsPlatformLayer()
2554 {
2555     if (!m_contentsLayer)
2556         return;
2557
2558     // Platform layer was set as m_contentsLayer, and will get parented in updateSublayerList().
2559     setupContentsLayer(m_contentsLayer.get());
2560
2561     if (m_contentsLayerPurpose == ContentsLayerPurpose::Canvas)
2562         m_contentsLayer->setNeedsDisplay();
2563
2564     updateContentsRects();
2565 }
2566
2567 void GraphicsLayerCA::updateContentsColorLayer()
2568 {
2569     // Color layer was set as m_contentsLayer, and will get parented in updateSublayerList().
2570     if (!m_contentsLayer || m_contentsLayerPurpose != ContentsLayerPurpose::BackgroundColor)
2571         return;
2572
2573     setupContentsLayer(m_contentsLayer.get());
2574     updateContentsRects();
2575     ASSERT(m_contentsSolidColor.isValid());
2576     m_contentsLayer->setBackgroundColor(m_contentsSolidColor);
2577
2578     if (m_layerClones) {
2579         for (auto& layer : m_layerClones->contentsLayerClones.values())
2580             layer->setBackgroundColor(m_contentsSolidColor);
2581     }
2582 }
2583
2584 // The clipping strategy depends on whether the rounded rect has equal corner radii.
2585 void GraphicsLayerCA::updateClippingStrategy(PlatformCALayer& clippingLayer, RefPtr<PlatformCALayer>& shapeMaskLayer, const FloatRoundedRect& roundedRect)
2586 {
2587     if (roundedRect.radii().isUniformCornerRadius()) {
2588         clippingLayer.setMask(nullptr);
2589         if (shapeMaskLayer) {
2590             shapeMaskLayer->setOwner(nullptr);
2591             shapeMaskLayer = nullptr;
2592         }
2593
2594         clippingLayer.setMasksToBounds(true);
2595         clippingLayer.setCornerRadius(roundedRect.radii().topLeft().width());
2596         return;
2597     }
2598
2599     if (!shapeMaskLayer) {
2600         shapeMaskLayer = createPlatformCALayer(PlatformCALayer::LayerTypeShapeLayer, this);
2601         shapeMaskLayer->setAnchorPoint({ });
2602         shapeMaskLayer->setName("shape mask");
2603     }
2604     
2605     shapeMaskLayer->setPosition(roundedRect.rect().location());
2606     FloatRect shapeBounds({ }, roundedRect.rect().size());
2607     shapeMaskLayer->setBounds(shapeBounds);
2608     FloatRoundedRect offsetRoundedRect(shapeBounds, roundedRect.radii());
2609     shapeMaskLayer->setShapeRoundedRect(offsetRoundedRect);
2610
2611     clippingLayer.setCornerRadius(0);
2612     clippingLayer.setMask(shapeMaskLayer.get());
2613 }
2614
2615 void GraphicsLayerCA::updateContentsRects()
2616 {
2617     if (!m_contentsLayer)
2618         return;
2619
2620     FloatPoint contentOrigin;
2621     const FloatRect contentBounds(0, 0, m_contentsRect.width(), m_contentsRect.height());
2622
2623     FloatPoint clippingOrigin(m_contentsClippingRect.rect().location());
2624     FloatRect clippingBounds(FloatPoint(), m_contentsClippingRect.rect().size());
2625     
2626     bool gainedOrLostClippingLayer = false;
2627     if (m_contentsClippingRect.isRounded() || !m_contentsClippingRect.rect().contains(m_contentsRect)) {
2628         if (!m_contentsClippingLayer) {
2629             m_contentsClippingLayer = createPlatformCALayer(PlatformCALayer::LayerTypeLayer, this);
2630             m_contentsClippingLayer->setAnchorPoint(FloatPoint());
2631 #if ENABLE(TREE_DEBUGGING)
2632             m_contentsClippingLayer->setName(makeString("contents clipping ", m_contentsClippingLayer->layerID()));
2633 #else
2634             m_contentsClippingLayer->setName("contents clipping");
2635 #endif
2636             gainedOrLostClippingLayer = true;
2637         }
2638
2639         m_contentsClippingLayer->setPosition(clippingOrigin);
2640         m_contentsClippingLayer->setBounds(clippingBounds);
2641
2642         updateClippingStrategy(*m_contentsClippingLayer, m_contentsShapeMaskLayer, m_contentsClippingRect);
2643
2644         if (gainedOrLostClippingLayer) {
2645             m_contentsLayer->removeFromSuperlayer();
2646             m_contentsClippingLayer->appendSublayer(*m_contentsLayer);
2647         }
2648     
2649         contentOrigin = FloatPoint(m_contentsRect.location() - m_contentsClippingRect.rect().location());
2650     } else {
2651         if (m_contentsClippingLayer) {
2652             m_contentsLayer->removeFromSuperlayer();
2653
2654             m_contentsClippingLayer->removeFromSuperlayer();
2655             m_contentsClippingLayer->setOwner(nullptr);
2656             m_contentsClippingLayer->setMask(nullptr);
2657             m_contentsClippingLayer = nullptr;
2658             gainedOrLostClippingLayer = true;
2659         }
2660
2661         if (m_contentsShapeMaskLayer) {
2662             m_contentsShapeMaskLayer->setOwner(nullptr);
2663             m_contentsShapeMaskLayer = nullptr;
2664         }
2665
2666         contentOrigin = m_contentsRect.location();
2667     }
2668     
2669     if (gainedOrLostClippingLayer)
2670         noteSublayersChanged(DontScheduleFlush);
2671
2672     m_contentsLayer->setPosition(contentOrigin);
2673     m_contentsLayer->setBounds(contentBounds);
2674
2675     if (m_layerClones) {
2676         for (auto& layer : m_layerClones->contentsLayerClones.values()) {
2677             layer->setPosition(contentOrigin);
2678             layer->setBounds(contentBounds);
2679         }
2680
2681         for (auto& clone : m_layerClones->contentsClippingLayerClones) {
2682             CloneID cloneID = clone.key;
2683             RefPtr<PlatformCALayer> shapeMaskLayerClone = m_layerClones->contentsShapeMaskLayerClones.get(cloneID);
2684
2685             bool hadShapeMask = shapeMaskLayerClone;
2686             updateClippingStrategy(*clone.value, shapeMaskLayerClone, m_contentsClippingRect);
2687
2688             if (!shapeMaskLayerClone)
2689                 m_layerClones->contentsShapeMaskLayerClones.remove(cloneID);
2690             else if (shapeMaskLayerClone && !hadShapeMask)
2691                 m_layerClones->contentsShapeMaskLayerClones.add(cloneID, shapeMaskLayerClone);
2692         }
2693     }
2694 }
2695
2696 void GraphicsLayerCA::updateMasksToBoundsRect()
2697 {
2698     updateClippingStrategy(*m_layer, m_shapeMaskLayer, m_masksToBoundsRect);
2699
2700     if (m_layerClones) {
2701         for (auto& clone : m_layerClones->primaryLayerClones) {
2702             CloneID cloneID = clone.key;
2703             RefPtr<PlatformCALayer> shapeMaskLayerClone = m_layerClones->shapeMaskLayerClones.get(cloneID);
2704
2705             bool hadShapeMask = shapeMaskLayerClone;
2706             updateClippingStrategy(*clone.value, shapeMaskLayerClone, m_masksToBoundsRect);
2707
2708             if (!shapeMaskLayerClone)
2709                 m_layerClones->shapeMaskLayerClones.remove(cloneID);
2710             else if (!hadShapeMask && shapeMaskLayerClone)
2711                 m_layerClones->shapeMaskLayerClones.add(cloneID, shapeMaskLayerClone);
2712         }
2713     }
2714 }
2715
2716 void GraphicsLayerCA::updateEventRegion()
2717 {
2718     m_layer->setEventRegion(eventRegion());
2719 }
2720
2721 void GraphicsLayerCA::updateMaskLayer()
2722 {
2723     PlatformCALayer* maskCALayer = m_maskLayer ? downcast<GraphicsLayerCA>(*m_maskLayer).primaryLayer() : nullptr;
2724     
2725     LayerMap* layerCloneMap;
2726     if (m_structuralLayer && structuralLayerPurpose() == StructuralLayerForBackdrop) {
2727         m_structuralLayer->setMask(maskCALayer);
2728         layerCloneMap = m_layerClones ? &m_layerClones->structuralLayerClones : nullptr;
2729     } else {
2730         m_layer->setMask(maskCALayer);
2731         layerCloneMap = m_layerClones ? &m_layerClones->primaryLayerClones : nullptr;
2732     }
2733
2734     LayerMap* maskLayerCloneMap = m_maskLayer ? downcast<GraphicsLayerCA>(*m_maskLayer).primaryLayerClones() : nullptr;
2735     if (layerCloneMap) {
2736         for (auto& clone : *layerCloneMap) {
2737             PlatformCALayer* maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(clone.key) : nullptr;
2738             clone.value->setMask(maskClone);
2739         }
2740     }
2741 }
2742
2743 void GraphicsLayerCA::updateReplicatedLayers()
2744 {
2745     // Clone the descendants of the replicated layer, and parent under us.
2746     ReplicaState replicaState(ReplicaState::ReplicaBranch);
2747
2748     RefPtr<PlatformCALayer>replicaRoot = replicatedLayerRoot(replicaState);
2749     if (!replicaRoot)
2750         return;
2751
2752     if (m_structuralLayer)
2753         m_structuralLayer->insertSublayer(*replicaRoot, 0);
2754     else
2755         m_layer->insertSublayer(*replicaRoot, 0);
2756 }
2757
2758 // For now, this assumes that layers only ever have one replica, so replicaIndices contains only 0 and 1.
2759 GraphicsLayerCA::CloneID GraphicsLayerCA::ReplicaState::cloneID() const
2760 {
2761     size_t depth = m_replicaBranches.size();
2762
2763     const size_t bitsPerUChar = sizeof(UChar) * 8;
2764     size_t vectorSize = (depth + bitsPerUChar - 1) / bitsPerUChar;
2765     
2766     Vector<UChar> result(vectorSize);
2767     result.fill(0);
2768
2769     // Create a string from the bit sequence which we can use to identify the clone.
2770     // Note that the string may contain embedded nulls, but that's OK.
2771     for (size_t i = 0; i < depth; ++i) {
2772         UChar& currChar = result[i / bitsPerUChar];
2773         currChar = (currChar << 1) | m_replicaBranches[i];
2774     }
2775     
2776     return String::adopt(WTFMove(result));
2777 }
2778
2779 RefPtr<PlatformCALayer> GraphicsLayerCA::replicatedLayerRoot(ReplicaState& replicaState)
2780 {
2781     // Limit replica nesting, to avoid 2^N explosion of replica layers.
2782     if (!m_replicatedLayer || replicaState.replicaDepth() == ReplicaState::maxReplicaDepth)
2783         return nullptr;
2784
2785     GraphicsLayerCA& replicatedLayer = downcast<GraphicsLayerCA>(*m_replicatedLayer);
2786     
2787     RefPtr<PlatformCALayer> clonedLayerRoot = replicatedLayer.fetchCloneLayers(this, replicaState, RootCloneLevel);
2788     FloatPoint cloneRootPosition = replicatedLayer.positionForCloneRootLayer();
2789
2790     // Replica root has no offset or transform
2791     clonedLayerRoot->setPosition(cloneRootPosition);
2792     clonedLayerRoot->setTransform(TransformationMatrix());
2793
2794     return clonedLayerRoot;
2795 }
2796
2797 void GraphicsLayerCA::updateAnimations()
2798 {
2799     if (!hasAnimations())
2800         return;
2801
2802     size_t numAnimations;
2803     if ((numAnimations = m_animations->uncomittedAnimations.size())) {
2804         for (size_t i = 0; i < numAnimations; ++i) {
2805             const LayerPropertyAnimation& pendingAnimation = m_animations->uncomittedAnimations[i];
2806             setAnimationOnLayer(*pendingAnimation.m_animation, pendingAnimation.m_property, pendingAnimation.m_name, pendingAnimation.m_index, pendingAnimation.m_subIndex, pendingAnimation.m_timeOffset);
2807
2808             AnimationsMap::iterator it = m_animations->runningAnimations.find(pendingAnimation.m_name);
2809             if (it == m_animations->runningAnimations.end()) {
2810                 Vector<LayerPropertyAnimation> animations;
2811                 animations.append(pendingAnimation);
2812                 m_animations->runningAnimations.add(pendingAnimation.m_name, animations);
2813             } else {
2814                 Vector<LayerPropertyAnimation>& animations = it->value;
2815                 animations.append(pendingAnimation);
2816             }
2817         }
2818         m_animations->uncomittedAnimations.clear();
2819     }
2820
2821     if (m_animations->animationsToProcess.size()) {
2822         for (const auto& it : m_animations->animationsToProcess) {
2823             const String& currentAnimationName = it.key;
2824             auto animationIterator = m_animations->runningAnimations.find(currentAnimationName);
2825             if (animationIterator == m_animations->runningAnimations.end())
2826                 continue;
2827
2828             for (const auto& processingInfo : it.value) {
2829                 const Vector<LayerPropertyAnimation>& animations = animationIterator->value;
2830                 for (const auto& currentAnimation : animations) {
2831                     switch (processingInfo.action) {
2832                     case Remove:
2833                         removeCAAnimationFromLayer(currentAnimation.m_property, currentAnimationName, currentAnimation.m_index, currentAnimation.m_subIndex);
2834                         break;
2835                     case Pause:
2836                         pauseCAAnimationOnLayer(currentAnimation.m_property, currentAnimationName, currentAnimation.m_index, currentAnimation.m_subIndex, processingInfo.timeOffset);
2837                         break;
2838                     case Seek:
2839                         seekCAAnimationOnLayer(currentAnimation.m_property, currentAnimationName, currentAnimation.m_index, currentAnimation.m_subIndex, processingInfo.timeOffset);
2840                         break;
2841                     }
2842                 }
2843
2844                 if (processingInfo.action == Remove)
2845                     m_animations->runningAnimations.remove(currentAnimationName);
2846             }
2847         }
2848
2849         m_animations->animationsToProcess.clear();
2850     }
2851 }
2852
2853 bool GraphicsLayerCA::isRunningTransformAnimation() const
2854 {
2855     if (!hasAnimations())
2856         return false;
2857
2858     for (const auto& it : m_animations->runningAnimations) {
2859         const auto& propertyAnimations = it.value;
2860         size_t numAnimations = propertyAnimations.size();
2861         for (size_t i = 0; i < numAnimations; ++i) {
2862             const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
2863             if (currAnimation.m_property == AnimatedPropertyTransform)
2864                 return true;
2865         }
2866     }
2867     return false;
2868 }
2869
2870 void GraphicsLayerCA::ensureLayerAnimations()
2871 {
2872     if (!m_animations)
2873         m_animations = std::make_unique<LayerAnimations>();
2874 }
2875
2876 void GraphicsLayerCA::setAnimationOnLayer(PlatformCAAnimation& caAnim, AnimatedPropertyID property, const String& animationName, int index, int subIndex, Seconds timeOffset)
2877 {
2878     PlatformCALayer* layer = animatedLayer(property);
2879
2880     if (timeOffset)
2881         caAnim.setBeginTime(CACurrentMediaTime() - timeOffset.seconds());
2882
2883     String animationID = animationIdentifier(animationName, property, index, subIndex);
2884
2885     layer->removeAnimationForKey(animationID);
2886     layer->addAnimationForKey(animationID, caAnim);
2887
2888     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
2889         for (auto& clone : *layerCloneMap) {
2890             // Skip immediate replicas, since they move with the original.
2891             if (m_replicaLayer && isReplicatedRootClone(clone.key))
2892                 continue;
2893
2894             clone.value->removeAnimationForKey(animationID);
2895             clone.value->addAnimationForKey(animationID, caAnim);
2896         }
2897     }
2898 }
2899
2900 // Workaround for <rdar://problem/7311367>
2901 static void bug7311367Workaround(PlatformCALayer* transformLayer, const TransformationMatrix& transform)
2902 {
2903     if (!transformLayer)
2904         return;
2905
2906     TransformationMatrix caTransform = transform;
2907     caTransform.setM41(caTransform.m41() + 1);
2908     transformLayer->setTransform(caTransform);
2909
2910     caTransform.setM41(caTransform.m41() - 1);
2911     transformLayer->setTransform(caTransform);
2912 }
2913
2914 bool GraphicsLayerCA::removeCAAnimationFromLayer(AnimatedPropertyID property, const String& animationName, int index, int subIndex)
2915 {
2916     PlatformCALayer* layer = animatedLayer(property);
2917
2918     String animationID = animationIdentifier(animationName, property, index, subIndex);
2919
2920     if (!layer->animationForKey(animationID))
2921         return false;
2922     
2923     layer->removeAnimationForKey(animationID);
2924     bug7311367Workaround(m_structuralLayer.get(), transform());
2925
2926     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
2927         for (auto& clone : *layerCloneMap) {
2928             // Skip immediate replicas, since they move with the original.
2929             if (m_replicaLayer && isReplicatedRootClone(clone.key))
2930                 continue;
2931
2932             clone.value->removeAnimationForKey(animationID);
2933         }
2934     }
2935     return true;
2936 }
2937
2938 void GraphicsLayerCA::pauseCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, int subIndex, Seconds timeOffset)
2939 {
2940     PlatformCALayer* layer = animatedLayer(property);
2941
2942     String animationID = animationIdentifier(animationName, property, index, subIndex);
2943
2944     RefPtr<PlatformCAAnimation> curAnim = layer->animationForKey(animationID);
2945     if (!curAnim)
2946         return;
2947
2948     // Animations on the layer are immutable, so we have to clone and modify.
2949     RefPtr<PlatformCAAnimation> newAnim = curAnim->copy();
2950
2951     newAnim->setSpeed(0);
2952     newAnim->setTimeOffset(timeOffset.seconds());
2953     
2954     layer->addAnimationForKey(animationID, *newAnim); // This will replace the running animation.
2955
2956     // Pause the animations on the clones too.
2957     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
2958         for (auto& clone : *layerCloneMap) {
2959             // Skip immediate replicas, since they move with the original.
2960             if (m_replicaLayer && isReplicatedRootClone(clone.key))
2961                 continue;
2962             clone.value->addAnimationForKey(animationID, *newAnim);
2963         }
2964     }
2965 }
2966
2967 void GraphicsLayerCA::seekCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, int subIndex, Seconds timeOffset)
2968 {
2969     // FIXME: this can be refactored a fair bit or merged with pauseCAAnimationOnLayer() with an operation flag.
2970     PlatformCALayer* layer = animatedLayer(property);
2971
2972     String animationID = animationIdentifier(animationName, property, index, subIndex);
2973
2974     RefPtr<PlatformCAAnimation> currentAnimation = layer->animationForKey(animationID);
2975     if (!currentAnimation)
2976         return;
2977
2978     // Animations on the layer are immutable, so we have to clone and modify.
2979     RefPtr<PlatformCAAnimation> newAnim = currentAnimation->copy();
2980
2981     newAnim->setBeginTime(CACurrentMediaTime());
2982     newAnim->setTimeOffset(timeOffset.seconds());
2983
2984     layer->addAnimationForKey(animationID, *newAnim); // This will replace the running animation.
2985
2986     // Pause the animations on the clones too.
2987     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
2988         for (auto& clone : *layerCloneMap) {
2989             // Skip immediate replicas, since they move with the original.
2990             if (m_replicaLayer && isReplicatedRootClone(clone.key))
2991                 continue;
2992             clone.value->addAnimationForKey(animationID, *newAnim);
2993         }
2994     }
2995 }
2996
2997 void GraphicsLayerCA::repaintLayerDirtyRects()
2998 {
2999     if (m_needsFullRepaint) {
3000         ASSERT(!m_dirtyRects.size());
3001         m_layer->setNeedsDisplay();
3002         m_needsFullRepaint = false;
3003         return;
3004     }
3005
3006     for (auto& dirtyRect : m_dirtyRects)
3007         m_layer->setNeedsDisplayInRect(dirtyRect);
3008     
3009     m_dirtyRects.clear();
3010 }
3011
3012 void GraphicsLayerCA::updateContentsNeedsDisplay()
3013 {
3014     if (m_contentsLayer)
3015         m_contentsLayer->setNeedsDisplay();
3016 }
3017
3018 bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, Seconds timeOffset)
3019 {
3020     ASSERT(valueList.property() != AnimatedPropertyTransform && (!supportsAcceleratedFilterAnimations() || valueList.property() != AnimatedPropertyFilter));
3021
3022     bool isKeyframe = valueList.size() > 2;
3023     bool valuesOK;
3024     
3025     bool additive = false;
3026     int animationIndex = 0;
3027     
3028     RefPtr<PlatformCAAnimation> caAnimation;
3029
3030     if (isKeyframe) {
3031         caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
3032         valuesOK = setAnimationKeyframes(valueList, animation, caAnimation.get());
3033     } else {
3034         if (animation->timingFunction()->isSpringTimingFunction())
3035             caAnimation = createSpringAnimation(animation, propertyIdToString(valueList.property()), additive);
3036         else
3037             caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
3038         valuesOK = setAnimationEndpoints(valueList, animation, caAnimation.get());
3039     }
3040
3041     if (!valuesOK)
3042         return false;
3043
3044     appendToUncommittedAnimations(LayerPropertyAnimation(caAnimation.releaseNonNull(), animationName, valueList.property(), animationIndex, 0, timeOffset));
3045
3046     return true;
3047 }
3048
3049 bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const TransformOperations* operations, const Animation* animation, const String& animationName, const FloatSize& boxSize, int animationIndex, Seconds timeOffset, bool isMatrixAnimation)
3050 {
3051     TransformOperation::OperationType transformOp = isMatrixAnimation ? TransformOperation::MATRIX_3D : operations->operations().at(animationIndex)->type();
3052 #if !PLATFORM(WIN) && !HAVE(CA_WHERE_ADDITIVE_TRANSFORMS_ARE_REVERSED)
3053     bool additive = animationIndex > 0;
3054 #else
3055     int numAnimations = isMatrixAnimation ? 1 : operations->size();
3056     bool additive = animationIndex < numAnimations - 1;
3057 #endif
3058     bool isKeyframe = valueList.size() > 2;
3059
3060     RefPtr<PlatformCAAnimation> caAnimation;
3061     bool validMatrices = true;
3062     if (isKeyframe) {
3063         caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
3064         validMatrices = setTransformAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
3065     } else {
3066         if (animation->timingFunction()->isSpringTimingFunction())
3067             caAnimation = createSpringAnimation(animation, propertyIdToString(valueList.property()), additive);
3068         else
3069             caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
3070         validMatrices = setTransformAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
3071     }
3072     
3073     if (!validMatrices)
3074         return false;
3075
3076     appendToUncommittedAnimations(LayerPropertyAnimation(caAnimation.releaseNonNull(), animationName, valueList.property(), animationIndex, 0, timeOffset));
3077     return true;
3078 }
3079
3080 bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, Seconds timeOffset, const FloatSize& boxSize)
3081 {
3082     ASSERT(valueList.property() == AnimatedPropertyTransform);
3083
3084     bool hasBigRotation;
3085     int listIndex = validateTransformOperations(valueList, hasBigRotation);
3086     const TransformOperations* operations = (listIndex >= 0) ? &static_cast<const TransformAnimationValue&>(valueList.at(listIndex)).value() : 0;
3087
3088     bool validMatrices = true;
3089
3090     // If function lists don't match we do a matrix animation, otherwise we do a component hardware animation.
3091     bool isMatrixAnimation = listIndex < 0;
3092     int numAnimations = isMatrixAnimation ? 1 : operations->size();
3093
3094 #if !PLATFORM(WIN) && !HAVE(CA_WHERE_ADDITIVE_TRANSFORMS_ARE_REVERSED)
3095     for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
3096 #else
3097     // Some versions of CA require animation lists to be applied in reverse order (<rdar://problem/43908047> and <rdar://problem/9112233>).
3098     for (int animationIndex = numAnimations - 1; animationIndex >= 0; --animationIndex) {
3099 #endif
3100         if (!appendToUncommittedAnimations(valueList, operations, animation, animationName, boxSize, animationIndex, timeOffset, isMatrixAnimation)) {
3101             validMatrices = false;
3102             break;
3103         }
3104     }
3105
3106     return validMatrices;
3107 }
3108
3109 bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const FilterOperation* operation, const Animation* animation, const String& animationName, int animationIndex, Seconds timeOffset)
3110 {
3111     bool isKeyframe = valueList.size() > 2;
3112     
3113     FilterOperation::OperationType filterOp = operation->type();
3114     int numAnimatedProperties = PlatformCAFilters::numAnimatedFilterProperties(filterOp);
3115     
3116     // Each filter might need to animate multiple properties, each with their own keyPath. The keyPath is always of the form:
3117     //
3118     //      filter.filter_<animationIndex>.<filterPropertyName>
3119     //
3120     // PlatformCAAnimation tells us how many properties each filter has and we iterate that many times and create an animation
3121     // for each. This internalFilterPropertyIndex gets passed to PlatformCAAnimation so it can properly create the property animation
3122     // values.
3123     for (int internalFilterPropertyIndex = 0; internalFilterPropertyIndex < numAnimatedProperties; ++internalFilterPropertyIndex) {
3124         bool valuesOK;
3125         RefPtr<PlatformCAAnimation> caAnimation;
3126         String keyPath = makeString("filters.filter_", animationIndex, '.', PlatformCAFilters::animatedFilterPropertyName(filterOp, internalFilterPropertyIndex));
3127         
3128         if (isKeyframe) {
3129             caAnimation = createKeyframeAnimation(animation, keyPath, false);
3130             valuesOK = setFilterAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex, filterOp);
3131         } else {
3132             caAnimation = createBasicAnimation(animation, keyPath, false);
3133             valuesOK = setFilterAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex);
3134         }
3135         
3136         ASSERT(valuesOK);
3137
3138         appendToUncommittedAnimations(LayerPropertyAnimation(caAnimation.releaseNonNull(), animationName, valueList.property(), animationIndex, internalFilterPropertyIndex, timeOffset));
3139     }
3140
3141     return true;
3142 }
3143
3144 void GraphicsLayerCA::appendToUncommittedAnimations(LayerPropertyAnimation&& animation)
3145 {
3146     ensureLayerAnimations();
3147
3148     // Since we're adding a new animation, make sure we clear any pending AnimationProcessingAction for this animation
3149     // as these are applied after we've committed new animations.
3150     m_animations->animationsToProcess.remove(animation.m_name);
3151
3152     m_animations->uncomittedAnimations.append(WTFMove(animation));
3153 }
3154
3155 bool GraphicsLayerCA::createFilterAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, Seconds timeOffset)
3156 {
3157 #if ENABLE(FILTERS_LEVEL_2)
3158     ASSERT(valueList.property() == AnimatedPropertyFilter || valueList.property() == AnimatedPropertyWebkitBackdropFilter);
3159 #else
3160     ASSERT(valueList.property() == AnimatedPropertyFilter);
3161 #endif
3162
3163     int listIndex = validateFilterOperations(valueList);
3164     if (listIndex < 0)
3165         return false;
3166
3167     const FilterOperations& operations = static_cast<const FilterAnimationValue&>(valueList.at(listIndex)).value();
3168     // Make sure the platform layer didn't fallback to using software filter compositing instead.
3169     if (!filtersCanBeComposited(operations))
3170         return false;
3171
3172     int numAnimations = operations.size();
3173
3174     // FIXME: We can't currently hardware animate shadows.
3175     for (int i = 0; i < numAnimations; ++i) {
3176         if (operations.at(i)->type() == FilterOperation::DROP_SHADOW)
3177             return false;
3178     }
3179
3180     for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
3181         if (!appendToUncommittedAnimations(valueList, operations.operations().at(animationIndex).get(), animation, animationName, animationIndex, timeOffset))
3182             return false;
3183     }
3184
3185     return true;
3186 }
3187
3188 Ref<PlatformCAAnimation> GraphicsLayerCA::createBasicAnimation(const Animation* anim, const String& keyPath, bool additive)
3189 {
3190     auto basicAnim = createPlatformCAAnimation(PlatformCAAnimation::Basic, keyPath);
3191     setupAnimation(basicAnim.ptr(), anim, additive);
3192     return basicAnim;
3193 }
3194
3195 Ref<PlatformCAAnimation> GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, const String& keyPath, bool additive)
3196 {
3197     auto keyframeAnim = createPlatformCAAnimation(PlatformCAAnimation::Keyframe, keyPath);
3198     setupAnimation(keyframeAnim.ptr(), anim, additive);
3199     return keyframeAnim;
3200 }
3201
3202 Ref<PlatformCAAnimation> GraphicsLayerCA::createSpringAnimation(const Animation* anim, const String& keyPath, bool additive)
3203 {
3204     auto basicAnim = createPlatformCAAnimation(PlatformCAAnimation::Spring, keyPath);
3205     setupAnimation(basicAnim.ptr(), anim, additive);
3206     return basicAnim;
3207 }
3208
3209 void GraphicsLayerCA::setupAnimation(PlatformCAAnimation* propertyAnim, const Animation* anim, bool additive)
3210 {
3211     double duration = anim->duration();
3212     if (duration <= 0)
3213         duration = cAnimationAlmostZeroDuration;
3214
3215     float repeatCount = anim->iterationCount();
3216     if (repeatCount == Animation::IterationCountInfinite)
3217         repeatCount = std::numeric_limits<float>::max();
3218     else if (anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse)
3219         repeatCount /= 2;
3220
3221     PlatformCAAnimation::FillModeType fillMode = PlatformCAAnimation::NoFillMode;
3222     switch (anim->fillMode()) {
3223     case AnimationFillMode::None:
3224         fillMode = PlatformCAAnimation::Forwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash.
3225         break;
3226     case AnimationFillMode::Backwards:
3227         fillMode = PlatformCAAnimation::Both; // Use "both" rather than "backwards" because the style system will remove the animation when it is finished. This avoids a flash.
3228         break;
3229     case AnimationFillMode::Forwards:
3230         fillMode = PlatformCAAnimation::Forwards;
3231         break;
3232     case AnimationFillMode::Both:
3233         fillMode = PlatformCAAnimation::Both;
3234         break;
3235     }
3236
3237     propertyAnim->setDuration(duration);
3238     propertyAnim->setRepeatCount(repeatCount);
3239     propertyAnim->setAutoreverses(anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse);
3240     propertyAnim->setRemovedOnCompletion(false);
3241     propertyAnim->setAdditive(additive);
3242     propertyAnim->setFillMode(fillMode);
3243 }
3244
3245 const TimingFunction& GraphicsLayerCA::timingFunctionForAnimationValue(const AnimationValue& animValue, const Animation& anim)
3246 {
3247     if (animValue.timingFunction())
3248         return *animValue.timingFunction();
3249     if (anim.isTimingFunctionSet())
3250         return *anim.timingFunction();
3251     return CubicBezierTimingFunction::defaultTimingFunction();
3252 }
3253
3254 bool GraphicsLayerCA::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim)
3255 {
3256     bool forwards = animation->directionIsForwards();
3257
3258     unsigned fromIndex = !forwards;
3259     unsigned toIndex = forwards;
3260     
3261     switch (valueList.property()) {
3262     case AnimatedPropertyOpacity: {
3263         basicAnim->setFromValue(static_cast<const FloatAnimationValue&>(valueList.at(fromIndex)).value());
3264         basicAnim->setToValue(static_cast<const FloatAnimationValue&>(valueList.at(toIndex)).value());
3265         break;
3266     }
3267     default:
3268         ASSERT_NOT_REACHED(); // we don't animate color yet
3269         break;
3270     }
3271
3272     // This codepath is used for 2-keyframe animations, so we still need to look in the start
3273     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
3274     basicAnim->setTimingFunction(&timingFunctionForAnimationValue(valueList.at(0), *animation), !forwards);
3275
3276     return true;
3277 }
3278
3279 bool GraphicsLayerCA::setAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim)
3280 {
3281     Vector<float> keyTimes;
3282     Vector<float> values;
3283     Vector<const TimingFunction*> timingFunctions;
3284
3285     bool forwards = animation->directionIsForwards();
3286     
3287     for (unsigned i = 0; i < valueList.size(); ++i) {
3288         unsigned index = forwards ? i : (valueList.size() - i - 1);
3289         const AnimationValue& curValue = valueList.at(index);
3290         keyTimes.append(forwards ? curValue.keyTime() : (1 - curValue.keyTime()));
3291
3292         switch (valueList.property()) {
3293         case AnimatedPropertyOpacity: {
3294             const FloatAnimationValue& floatValue = static_cast<const FloatAnimationValue&>(curValue);
3295             values.append(floatValue.value());
3296             break;
3297         }
3298         default:
3299             ASSERT_NOT_REACHED(); // we don't animate color yet
3300             break;
3301         }
3302
3303         if (i < (valueList.size() - 1))
3304             timingFunctions.append(&timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), *animation));
3305     }
3306
3307     keyframeAnim->setKeyTimes(keyTimes);
3308     keyframeAnim->setValues(values);
3309     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
3310
3311     return true;
3312 }
3313
3314 bool GraphicsLayerCA::setTransformAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const FloatSize& boxSize)
3315 {
3316     ASSERT(valueList.size() == 2);
3317
3318     bool forwards = animation->directionIsForwards();
3319     
3320     unsigned fromIndex = !forwards;
3321     unsigned toIndex = forwards;
3322     
3323     auto& startValue = static_cast<const TransformAnimationValue&>(valueList.at(fromIndex));
3324     auto& endValue = static_cast<const TransformAnimationValue&>(valueList.at(toIndex));
3325
3326     if (isMatrixAnimation) {
3327         TransformationMatrix fromTransform, toTransform;
3328         startValue.value().apply(boxSize, fromTransform);
3329         endValue.value().apply(boxSize, toTransform);
3330
3331         // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
3332         if (!fromTransform.isInvertible() || !toTransform.isInvertible())
3333             return false;
3334
3335         basicAnim->setFromValue(fromTransform);
3336         basicAnim->setToValue(toTransform);
3337     } else {
3338         if (isTransformTypeNumber(transformOpType)) {
3339             float fromValue;
3340             getTransformFunctionValue(startValue.value().at(functionIndex), transformOpType, boxSize, fromValue);
3341             basicAnim->setFromValue(fromValue);
3342             
3343             float toValue;
3344             getTransformFunctionValue(endValue.value().at(functionIndex), transformOpType, boxSize, toValue);
3345             basicAnim->setToValue(toValue);
3346         } else if (isTransformTypeFloatPoint3D(transformOpType)) {
3347             FloatPoint3D fromValue;
3348             getTransformFunctionValue(startValue.value().at(functionIndex), transformOpType, boxSize, fromValue);
3349             basicAnim->setFromValue(fromValue);
3350             
3351             FloatPoint3D toValue;
3352             getTransformFunctionValue(endValue.value().at(functionIndex), transformOpType, boxSize, toValue);
3353             basicAnim->setToValue(toValue);
3354         } else {
3355             TransformationMatrix fromValue;
3356             getTransformFunctionValue(startValue.value().at(functionIndex), transformOpType, boxSize, fromValue);
3357             basicAnim->setFromValue(fromValue);
3358
3359             TransformationMatrix toValue;
3360             getTransformFunctionValue(endValue.value().at(functionIndex), transformOpType, boxSize, toValue);
3361             basicAnim->setToValue(toValue);
3362         }
3363     }
3364
3365     // This codepath is used for 2-keyframe animations, so we still need to look in the start
3366     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
3367     basicAnim->setTimingFunction(&timingFunctionForAnimationValue(valueList.at(0), *animation), !forwards);
3368
3369     auto valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
3370     if (valueFunction != PlatformCAAnimation::NoValueFunction)
3371         basicAnim->setValueFunction(valueFunction);
3372
3373     return true;
3374 }
3375
3376 bool GraphicsLayerCA::setTransformAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const FloatSize& boxSize)
3377 {
3378     Vector<float> keyTimes;
3379     Vector<float> floatValues;
3380     Vector<FloatPoint3D> floatPoint3DValues;
3381     Vector<TransformationMatrix> transformationMatrixValues;
3382     Vector<const TimingFunction*> timingFunctions;
3383
3384     bool forwards = animation->directionIsForwards();
3385
3386     for (unsigned i = 0; i < valueList.size(); ++i) {
3387         unsigned index = forwards ? i : (valueList.size() - i - 1);
3388         const TransformAnimationValue& curValue = static_cast<const TransformAnimationValue&>(valueList.at(index));
3389         keyTimes.append(forwards ? curValue.keyTime() : (1 - curValue.keyTime()));
3390
3391         TransformationMatrix transform;
3392
3393         if (isMatrixAnimation) {
3394             curValue.value().apply(boxSize, transform);
3395
3396             // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
3397             if (!transform.isInvertible())
3398                 return false;
3399
3400             transformationMatrixValues.append(transform);
3401         } else {
3402             const TransformOperation* transformOp = curValue.value().at(functionIndex);
3403             if (isTransformTypeNumber(transformOpType)) {
3404                 float value;
3405                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
3406                 floatValues.append(value);
3407             } else if (isTransformTypeFloatPoint3D(transformOpType)) {
3408                 FloatPoint3D value;
3409                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
3410                 floatPoint3DValues.append(value);
3411             } else {
3412                 TransformationMatrix value;
3413                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
3414                 transformationMatrixValues.append(value);
3415             }
3416
3417             curValue.value().apply(boxSize, transform);
3418         }
3419
3420         if (i < (valueList.size() - 1))
3421             timingFunctions.append(&timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), *animation));
3422     }
3423     
3424     keyframeAnim->setKeyTimes(keyTimes);
3425     
3426     if (isTransformTypeNumber(transformOpType))
3427         keyframeAnim->setValues(floatValues);
3428     else if (isTransformTypeFloatPoint3D(transformOpType))
3429         keyframeAnim->setValues(floatPoint3DValues);
3430     else
3431         keyframeAnim->setValues(transformationMatrixValues);
3432         
3433     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
3434
3435     PlatformCAAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
3436     if (valueFunction != PlatformCAAnimation::NoValueFunction)
3437         keyframeAnim->setValueFunction(valueFunction);
3438
3439     return true;
3440 }
3441
3442 bool GraphicsLayerCA::setFilterAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim, int functionIndex, int internalFilterPropertyIndex)
3443 {
3444     ASSERT(valueList.size() == 2);
3445
3446     bool forwards = animation->directionIsForwards();
3447
3448     unsigned fromIndex = !forwards;
3449     unsigned toIndex = forwards;
3450
3451     const FilterAnimationValue& fromValue = static_cast<const FilterAnimationValue&>(valueList.at(fromIndex));
3452     const FilterAnimationValue& toValue = static_cast<const FilterAnimationValue&>(valueList.at(toIndex));
3453
3454     const FilterOperation* fromOperation = fromValue.value().at(functionIndex);
3455     const FilterOperation* toOperation = toValue.value().at(functionIndex);
3456
3457     RefPtr<DefaultFilterOperation> defaultFromOperation;
3458     RefPtr<DefaultFilterOperation> defaultToOperation;
3459
3460     ASSERT(fromOperation || toOperation);
3461
3462     if (!fromOperation) {
3463         defaultFromOperation = DefaultFilterOperation::create(toOperation->type());
3464         fromOperation = defaultFromOperation.get();
3465     }
3466
3467     if (!toOperation) {
3468         defaultToOperation = DefaultFilterOperation::create(fromOperation->type());
3469         toOperation = defaultToOperation.get();
3470     }
3471
3472     basicAnim->setFromValue(fromOperation, internalFilterPropertyIndex);
3473     basicAnim->setToValue(toOperation, internalFilterPropertyIndex);
3474
3475     // This codepath is used for 2-keyframe animations, so we still need to look in the start
3476     // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
3477     basicAnim->setTimingFunction(&timingFunctionForAnimationValue(valueList.at(0), *animation), !forwards);
3478
3479     return true;
3480 }
3481
3482 bool GraphicsLayerCA::setFilterAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim, int functionIndex, int internalFilterPropertyIndex, FilterOperation::OperationType filterOp)
3483 {
3484     Vector<float> keyTimes;
3485     Vector<RefPtr<FilterOperation>> values;
3486     Vector<const TimingFunction*> timingFunctions;
3487     RefPtr<DefaultFilterOperation> defaultOperation;
3488
3489     bool forwards = animation->directionIsForwards();
3490
3491     for (unsigned i = 0; i < valueList.size(); ++i) {
3492         unsigned index = forwards ? i : (valueList.size() - i - 1);
3493         const FilterAnimationValue& curValue = static_cast<const FilterAnimationValue&>(valueList.at(index));
3494         keyTimes.append(forwards ? curValue.keyTime() : (1 - curValue.keyTime()));
3495
3496         if (curValue.value().operations().size() > static_cast<size_t>(functionIndex))
3497             values.append(curValue.value().operations()[functionIndex]);
3498         else {
3499             if (!defaultOperation)
3500                 defaultOperation = DefaultFilterOperation::create(filterOp);
3501             values.append(defaultOperation);
3502         }
3503
3504         if (i < (valueList.size() - 1))
3505             timingFunctions.append(&timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), *animation));
3506     }
3507     
3508     keyframeAnim->setKeyTimes(keyTimes);
3509     keyframeAnim->setValues(values, internalFilterPropertyIndex);
3510     keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
3511
3512     return true;
3513 }
3514
3515 void GraphicsLayerCA::suspendAnimations(MonotonicTime time)
3516 {
3517     double t = PlatformCALayer::currentTimeToMediaTime(time ? time : MonotonicTime::now());
3518     primaryLayer()->setSpeed(0);
3519     primaryLayer()->setTimeOffset(t);
3520
3521     // Suspend the animations on the clones too.
3522     if (LayerMap* layerCloneMap = primaryLayerClones()) {
3523         for (auto& layer : layerCloneMap->values()) {
3524             layer->setSpeed(0);
3525             layer->setTimeOffset(t);
3526         }
3527     }
3528 }
3529
3530 void GraphicsLayerCA::resumeAnimations()
3531 {
3532     primaryLayer()->setSpeed(1);
3533     primaryLayer()->setTimeOffset(0);
3534
3535     // Resume the animations on the clones too.
3536     if (LayerMap* layerCloneMap = primaryLayerClones()) {
3537         for (auto& layer : layerCloneMap->values()) {
3538             layer->setSpeed(1);
3539             layer->setTimeOffset(0);
3540         }
3541     }
3542 }
3543
3544 PlatformCALayer* GraphicsLayerCA::hostLayerForSublayers() const
3545 {
3546     return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); 
3547 }
3548
3549 PlatformCALayer* GraphicsLayerCA::layerForSuperlayer() const
3550 {
3551     return m_structuralLayer ? m_structuralLayer.get() : m_layer.get();
3552 }
3553
3554 PlatformCALayer* GraphicsLayerCA::animatedLayer(AnimatedPropertyID property) const
3555 {
3556     switch (property) {
3557     case AnimatedPropertyBackgroundColor:
3558         return m_contentsLayer.get();
3559 #if ENABLE(FILTERS_LEVEL_2)
3560     case AnimatedPropertyWebkitBackdropFilter:
3561         // FIXME: Should be just m_backdropLayer.get(). Also, add an ASSERT(m_backdropLayer) here when https://bugs.webkit.org/show_bug.cgi?id=145322 is fixed.
3562         return m_backdropLayer ? m_backdropLayer.get() : primaryLayer();
3563 #endif
3564     default:
3565         return primaryLayer();
3566     }
3567 }
3568
3569 GraphicsLayerCA::LayerMap* GraphicsLayerCA::primaryLayerClones() const
3570 {
3571     if (!m_layerClones)
3572         return nullptr;
3573
3574     return m_structuralLayer ? &m_layerClones->structuralLayerClones : &m_layerClones->primaryLayerClones;
3575 }
3576
3577 GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedPropertyID property) const
3578 {
3579     if (!m_layerClones)
3580         return nullptr;
3581
3582     return (property == AnimatedPropertyBackgroundColor) ? &m_layerClones->contentsLayerClones : primaryLayerClones();
3583 }
3584
3585 void GraphicsLayerCA::updateContentsScale(float pageScaleFactor)
3586 {
3587     float contentsScale = pageScaleFactor * deviceScaleFactor();
3588
3589     if (isPageTiledBackingLayer() && tiledBacking()) {
3590         float zoomedOutScale = client().zoomedOutPageScaleFactor() * deviceScaleFactor();
3591         tiledBacking()->setZoomedOutContentsScale(zoomedOutScale);
3592     }
3593
3594     if (contentsScale == m_layer->contentsScale())
3595         return;
3596
3597     m_layer->setContentsScale(contentsScale);
3598
3599     if (m_contentsLayer && m_contentsLayerPurpose == ContentsLayerPurpose::Media)
3600         m_contentsLayer->setContentsScale(contentsScale);
3601
3602     if (tiledBacking()) {
3603         // Tiled backing repaints automatically on scale change.
3604         return;
3605     }
3606
3607     if (drawsContent())
3608         m_layer->setNeedsDisplay();
3609 }
3610
3611 void GraphicsLayerCA::updateCustomAppearance()
3612 {
3613     m_layer->updateCustomAppearance(m_customAppearance);
3614 }
3615
3616 void GraphicsLayerCA::setShowDebugBorder(bool showBorder)
3617 {
3618     if (showBorder == m_showDebugBorder)
3619         return;
3620
3621     GraphicsLayer::setShowDebugBorder(showBorder);
3622     noteLayerPropertyChanged(DebugIndicatorsChanged);
3623 }
3624
3625 void GraphicsLayerCA::setShowRepaintCounter(bool showCounter)
3626 {
3627     if (showCounter == m_showRepaintCounter)
3628         return;
3629
3630     GraphicsLayer::setShowRepaintCounter(showCounter);
3631     noteLayerPropertyChanged(DebugIndicatorsChanged);
3632 }
3633
3634 String GraphicsLayerCA::displayListAsText(DisplayList::AsTextFlags flags) const
3635 {
3636     if (!m_displayList)
3637         return String();
3638
3639     return m_displayList->asText(flags);
3640 }
3641
3642 void GraphicsLayerCA::setIsTrackingDisplayListReplay(bool isTracking)
3643 {
3644     if (isTracking == m_isTrackingDisplayListReplay)
3645         return;
3646
3647     m_isTrackingDisplayListReplay = isTracking;
3648     if (!m_isTrackingDisplayListReplay)
3649         layerDisplayListMap().remove(this);
3650 }
3651
3652 String GraphicsLayerCA::replayDisplayListAsText(DisplayList::AsTextFlags flags) const
3653 {
3654     auto it = layerDisplayListMap().find(this);
3655     if (it != layerDisplayListMap().end()) {
3656         TextStream stream(TextStream::LineMode::MultipleLine, TextStream::Formatting::SVGStyleRect);
3657         
3658         TextStream::GroupScope scope(stream);
3659         stream.dumpProperty("clip", it->value.first);
3660         stream << it->value.second->asText(flags);
3661         return stream.release();
3662         
3663     }
3664
3665     return String();
3666 }
3667
3668 void GraphicsLayerCA::setDebugBackgroundColor(const Color& color)
3669 {    
3670     if (color.isValid())
3671         m_layer->setBackgroundColor(color);
3672     else
3673         m_layer->setBackgroundColor(Color::transparent);
3674 }
3675
3676 void GraphicsLayerCA::getDebugBorderInfo(Color& color, float& width) const
3677 {
3678     if (isPageTiledBackingLayer()) {
3679         color = Color(0, 0, 128, 128); // tile cache layer: dark blue
3680 #if OS(WINDOWS)
3681         width = 1.0;
3682 #else
3683         width = 0.5;
3684 #endif
3685         return;
3686     }
3687
3688     GraphicsLayer::getDebugBorderInfo(color, width);
3689 }
3690
3691 static void dumpInnerLayer(TextStream& textStream, String label, PlatformCALayer* layer, LayerTreeAsTextBehavior behavior)
3692 {
3693     if (!layer)
3694         return;
3695
3696     textStream << indent << "(" << label << " ";
3697     if (behavior & LayerTreeAsTextDebug)
3698         textStream << "id=" << layer->layerID() << " ";
3699     textStream << layer->position().x() << ", " << layer->position().y() << " " << layer->bounds().width() << " x " << layer->bounds().height();
3700     if (layer->isHidden())
3701         textStream << " hidden";
3702     textStream << ")\n";
3703 }
3704
3705 void GraphicsLayerCA::dumpAdditionalProperties(TextStream& textStream, LayerTreeAsTextBehavior behavior) const
3706 {
3707     if (behavior & LayerTreeAsTextIncludeVisibleRects) {
3708         textStream << indent << "(visible rect " << m_visibleRect.x() << ", " << m_visibleRect.y() << " " << m_visibleRect.width() << " x " << m_visibleRect.height() << ")\n";
3709         textStream << indent << "(coverage rect " << m_coverageRect.x() << ", " << m_coverageRect.y() << " " << m_coverageRect.width() << " x " << m_coverageRect.height() << ")\n";
3710         textStream << indent << "(intersects coverage rect " << m_intersectsCoverageRect << ")\n";
3711         textStream << indent << "(contentsScale " << m_layer->contentsScale() << ")\n";
3712     }
3713
3714     if (tiledBacking() && (behavior & LayerTreeAsTextIncludeTileCaches)) {
3715         if (behavior & LayerTreeAsTextDebug)
3716             textStream << indent << "(tiled backing " << tiledBacking() << ")\n";
3717
3718         IntRect tileCoverageRect = tiledBacking()->tileCoverageRect();
3719         textStream << indent << "(tile cache coverage " << tileCoverageRect.x() << ", " << tileCoverageRect.y() << " " << tileCoverageRect.width() << " x " << tileCoverageRect.height() << ")\n";
3720
3721         IntSize tileSize = tiledBacking()->tileSize();
3722         textStream << indent << "(tile size " << tileSize.width() << " x " << tileSize.height() << ")\n";
3723         
3724         IntRect gridExtent = tiledBacking()->tileGridExtent();
3725         textStream << indent << "(top left tile " << gridExtent.x() << ", " << gridExtent.y() << " tiles grid " << gridExtent.width() << " x " << gridExtent.height() << ")\n";
3726
3727         textStream << indent << "(in window " << tiledBacking()->isInWindow() << ")\n";
3728     }
3729
3730     if (m_layer->wantsDeepColorBackingStore())
3731         textStream << indent << "(deep color 1)\n";
3732
3733     if (behavior & LayerTreeAsTextIncludeContentLayers) {
3734         dumpInnerLayer(textStream, "structural layer", m_structuralLayer.get(), behavior);
3735         dumpInnerLayer(textStream, "contents clipping layer", m_contentsClippingLayer.get(), behavior);
3736         dumpInnerLayer(textStream, "shape mask layer", m_shapeMaskLayer.get(), behavior);
3737         dumpInnerLayer(textStream, "backdrop clipping layer", m_backdropClippingLayer.get(), behavior);
3738         dumpInnerLayer(textStream, "contents layer", m_contentsLayer.get(), behavior);
3739         dumpInnerLayer(textStream, "contents shape mask layer", m_contentsShapeMaskLayer.get(), behavior);
3740         dumpInnerLayer(textStream, "backdrop layer", m_backdropLayer.get(), behavior);
3741     }
3742
3743     if (behavior & LayerTreeAsTextDebug) {
3744         if (m_usesDisplayListDrawing)
3745             textStream << indent << "(uses display-list drawing " << m_usesDisplayListDrawing << ")\n";
3746     }
3747 }
3748
3749 void GraphicsLayerCA::setDebugBorder(const Color& color, float borderWidth)
3750 {
3751     setLayerDebugBorder(*m_layer, color, borderWidth);
3752 }
3753
3754 void GraphicsLayerCA::setCustomAppearance(CustomAppearance customAppearance)
3755 {
3756     if (customAppearance == m_customAppearance)
3757         return;
3758
3759     GraphicsLayer::setCustomAppearance(customAppearance);
3760     noteLayerPropertyChanged(CustomAppearanceChanged);
3761 }
3762
3763 bool GraphicsLayerCA::requiresTiledLayer(float pageScaleFactor) const
3764 {
3765     if (!m_drawsContent || isPageTiledBackingLayer())
3766         return false;
3767
3768     // FIXME: catch zero-size height or width here (or earlier)?
3769 #if PLATFORM(IOS_FAMILY)
3770     int maxPixelDimension = systemMemoryLevel() < cMemoryLevelToUseSmallerPixelDimension ? cMaxPixelDimensionLowMemory : cMaxPixelDimension;
3771     return m_size.width() * pageScaleFactor > maxPixelDimension || m_size.height() * pageScaleFactor > maxPixelDimension;
3772 #else
3773     return m_size.width() * pageScaleFactor > cMaxPixelDimension || m_size.height() * pageScaleFactor > cMaxPixelDimension;
3774 #endif
3775 }
3776
3777 void GraphicsLayerCA::changeLayerTypeTo(PlatformCALayer::LayerType newLayerType)
3778 {
3779     PlatformCALayer::LayerType oldLayerType = m_layer->layerType();
3780     if (newLayerType == oldLayerType)
3781         return;
3782
3783     bool wasTiledLayer = oldLayerType == PlatformCALayer::LayerTypeTiledBackingLayer;
3784     bool isTiledLayer = newLayerType == PlatformCALayer::LayerTypeTiledBackingLayer;
3785
3786     RefPtr<PlatformCALayer> oldLayer = m_layer;
3787     m_layer = createPlatformCALayer(newLayerType, this);
3788
3789     m_usingBackdropLayerType = isCustomBackdropLayerType(newLayerType);
3790
3791     m_layer->adoptSublayers(*oldLayer);
3792
3793 #ifdef VISIBLE_TILE_WASH
3794     if (m_visibleTileWashLayer)
3795         m_layer->appendSublayer(*m_visibleTileWashLayer;
3796 #endif
3797
3798     if (isMaskLayer()) {
3799         // A mask layer's superlayer is the layer that it masks. Set the MaskLayerChanged dirty bit
3800         // so that the parent will fix up the platform layers in commitLayerChangesAfterSublayers().
3801         if (GraphicsLayer* parentLayer = parent())
3802             downcast<GraphicsLayerCA>(*parentLayer).noteLayerPropertyChanged(MaskLayerChanged);
3803     } else if (oldLayer->superlayer()) {
3804         // Skip this step if we don't have a superlayer. This is probably a benign
3805         // case that happens while restructuring the layer tree, and also occurs with
3806         // WebKit2 page overlays, which can become tiled but are out-of-tree.
3807         oldLayer->superlayer()->replaceSublayer(*oldLayer, *m_layer);
3808     }
3809
3810     addUncommittedChanges(ChildrenChanged
3811         | GeometryChanged
3812         | TransformChanged
3813         | ChildrenTransformChanged
3814         | MasksToBoundsChanged
3815         | ContentsOpaqueChanged
3816         | BackfaceVisibilityChanged
3817         | BackgroundColorChanged
3818         | ContentsScaleChanged
3819         | AcceleratesDrawingChanged
3820         | SupportsSubpixelAntialiasedTextChanged
3821         | FiltersChanged
3822         | BackdropFiltersChanged
3823         | MaskLayerChanged
3824         | OpacityChanged
3825         | NameChanged
3826         | DebugIndicatorsChanged);
3827     
3828     if (isTiledLayer)
3829         addUncommittedChanges(CoverageRectChanged);
3830
3831     moveAnimations(oldLayer.get(), m_layer.get());
3832     
3833     // need to tell new layer to draw itself
3834     setNeedsDisplay();
3835
3836     if (wasTiledLayer || isTiledLayer)
3837         client().tiledBackingUsageChanged(this, isTiledLayer);
3838 }
3839
3840 GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayerCA::defaultContentsOrientation() const
3841 {
3842     return CompositingCoordinatesOrientation::TopDown;
3843 }
3844
3845 void GraphicsLayerCA::setupContentsLayer(PlatformCALayer* contentsLayer)
3846 {
3847     // Turn off implicit animations on the inner layer.
3848 #if !PLATFORM(IOS_FAMILY)
3849     contentsLayer->setMasksToBounds(true);
3850 #endif
3851
3852     if (defaultContentsOrientation() == CompositingCoordinatesOrientation::BottomUp) {
3853         TransformationMatrix flipper(
3854             1.0f, 0.0f, 0.0f, 0.0f,
3855             0.0f, -1.0f, 0.0f, 0.0f,
3856             0.0f, 0.0f, 1.0f, 0.0f,
3857             0.0f, 0.0f, 0.0f, 1.0f);
3858         contentsLayer->setTr