Combine event and touch action regions into a single class
[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         return true;
308     case Type::Shape:
309 #if PLATFORM(COCOA)
310         // FIXME: we can use shaper layers on Windows when PlatformCALayerCocoa::setShapePath() etc are implemented.
311         return true;
312 #else
313         return false;
314 #endif
315     }
316     ASSERT_NOT_REACHED();
317     return false;
318 }
319
320 bool GraphicsLayer::supportsBackgroundColorContent()
321 {
322     return true;
323 }
324
325 bool GraphicsLayer::supportsSubpixelAntialiasedLayerText()
326 {
327 #if PLATFORM(MAC)
328     return true;
329 #else
330     return false;
331 #endif
332 }
333
334 Ref<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient& client, Type layerType)
335 {
336     if (factory) {
337         auto layer = factory->createGraphicsLayer(layerType, client);
338         layer->initialize(layerType);
339         return layer;
340     }
341     
342     auto layer = adoptRef(*new GraphicsLayerCA(layerType, client));
343     layer->initialize(layerType);
344     return WTFMove(layer);
345 }
346
347 bool GraphicsLayerCA::filtersCanBeComposited(const FilterOperations& filters)
348 {
349 #if PLATFORM(COCOA)
350     return PlatformCALayerCocoa::filtersCanBeComposited(filters);
351 #elif PLATFORM(WIN)
352     return PlatformCALayerWin::filtersCanBeComposited(filters);
353 #endif
354 }
355
356 Ref<PlatformCALayer> GraphicsLayerCA::createPlatformCALayer(PlatformCALayer::LayerType layerType, PlatformCALayerClient* owner)
357 {
358 #if PLATFORM(COCOA)
359     auto result = PlatformCALayerCocoa::create(layerType, owner);
360     
361     if (result->canHaveBackingStore())
362         result->setWantsDeepColorBackingStore(screenSupportsExtendedColor());
363     
364     return result;
365 #elif PLATFORM(WIN)
366     return PlatformCALayerWin::create(layerType, owner);
367 #endif
368 }
369     
370 Ref<PlatformCALayer> GraphicsLayerCA::createPlatformCALayer(PlatformLayer* platformLayer, PlatformCALayerClient* owner)
371 {
372 #if PLATFORM(COCOA)
373     return PlatformCALayerCocoa::create(platformLayer, owner);
374 #elif PLATFORM(WIN)
375     return PlatformCALayerWin::create(platformLayer, owner);
376 #endif
377 }
378
379 Ref<PlatformCALayer> GraphicsLayerCA::createPlatformCALayerForEmbeddedView(PlatformCALayer::LayerType layerType, GraphicsLayer::EmbeddedViewID, PlatformCALayerClient* owner)
380 {
381     return GraphicsLayerCA::createPlatformCALayer(layerType, owner);
382 }
383
384 Ref<PlatformCAAnimation> GraphicsLayerCA::createPlatformCAAnimation(PlatformCAAnimation::AnimationType type, const String& keyPath)
385 {
386 #if PLATFORM(COCOA)
387     return PlatformCAAnimationCocoa::create(type, keyPath);
388 #elif PLATFORM(WIN)
389     return PlatformCAAnimationWin::create(type, keyPath);
390 #endif
391 }
392
393 typedef HashMap<const GraphicsLayerCA*, std::pair<FloatRect, std::unique_ptr<DisplayList::DisplayList>>> LayerDisplayListHashMap;
394
395 static LayerDisplayListHashMap& layerDisplayListMap()
396 {
397     static NeverDestroyed<LayerDisplayListHashMap> sharedHashMap;
398     return sharedHashMap;
399 }
400
401 GraphicsLayerCA::GraphicsLayerCA(Type layerType, GraphicsLayerClient& client)
402     : GraphicsLayer(layerType, client)
403     , m_needsFullRepaint(false)
404     , m_usingBackdropLayerType(false)
405     , m_isViewportConstrained(false)
406     , m_intersectsCoverageRect(false)
407     , m_hasEverPainted(false)
408     , m_hasDescendantsWithRunningTransformAnimations(false)
409     , m_hasDescendantsWithUncommittedChanges(false)
410 {
411 }
412
413 void GraphicsLayerCA::initialize(Type layerType)
414 {
415     PlatformCALayer::LayerType platformLayerType;
416     switch (layerType) {
417     case Type::Normal:
418         platformLayerType = PlatformCALayer::LayerType::LayerTypeWebLayer;
419         break;
420     case Type::PageTiledBacking:
421         platformLayerType = PlatformCALayer::LayerType::LayerTypePageTiledBackingLayer;
422         break;
423     case Type::ScrollContainer:
424         platformLayerType = PlatformCALayer::LayerType::LayerTypeScrollContainerLayer;
425         break;
426     case Type::Shape:
427         platformLayerType = PlatformCALayer::LayerType::LayerTypeShapeLayer;
428         break;
429     }
430     m_layer = createPlatformCALayer(platformLayerType, this);
431     noteLayerPropertyChanged(ContentsScaleChanged);
432 }
433
434 GraphicsLayerCA::~GraphicsLayerCA()
435 {
436     if (UNLIKELY(isTrackingDisplayListReplay()))
437         layerDisplayListMap().remove(this);
438
439     // Do cleanup while we can still safely call methods on the derived class.
440     willBeDestroyed();
441 }
442
443 void GraphicsLayerCA::willBeDestroyed()
444 {
445     // We release our references to the PlatformCALayers here, but do not actively unparent them,
446     // since that will cause a commit and break our batched commit model. The layers will
447     // get released when the rootmost modified GraphicsLayerCA rebuilds its child layers.
448
449     // Clean up the layer.
450     if (m_layer)
451         m_layer->setOwner(nullptr);
452     
453     if (m_contentsLayer)
454         m_contentsLayer->setOwner(nullptr);
455
456     if (m_contentsClippingLayer)
457         m_contentsClippingLayer->setOwner(nullptr);
458
459     if (m_contentsShapeMaskLayer)
460         m_contentsShapeMaskLayer->setOwner(nullptr);
461
462     if (m_shapeMaskLayer)
463         m_shapeMaskLayer->setOwner(nullptr);
464     
465     if (m_structuralLayer)
466         m_structuralLayer->setOwner(nullptr);
467
468     if (m_backdropLayer)
469         m_backdropLayer->setOwner(nullptr);
470
471     if (m_backdropClippingLayer)
472         m_backdropClippingLayer->setOwner(nullptr);
473
474     removeCloneLayers();
475
476     GraphicsLayer::willBeDestroyed();
477 }
478
479 void GraphicsLayerCA::setName(const String& name)
480 {
481 #if ENABLE(TREE_DEBUGGING)
482     String caLayerDescription;
483     if (!m_layer->isPlatformCALayerRemote())
484         caLayerDescription = makeString("CALayer(0x", hex(reinterpret_cast<uintptr_t>(m_layer->platformLayer()), Lowercase), ") ");
485     GraphicsLayer::setName(makeString(caLayerDescription, "GraphicsLayer(0x", hex(reinterpret_cast<uintptr_t>(this), Lowercase), ", ", primaryLayerID(), ") ", name));
486 #else
487     GraphicsLayer::setName(name);
488 #endif
489
490     noteLayerPropertyChanged(NameChanged);
491 }
492
493 GraphicsLayer::PlatformLayerID GraphicsLayerCA::primaryLayerID() const
494 {
495     return primaryLayer()->layerID();
496 }
497
498 PlatformLayer* GraphicsLayerCA::platformLayer() const
499 {
500     return primaryLayer()->platformLayer();
501 }
502
503 bool GraphicsLayerCA::setChildren(Vector<Ref<GraphicsLayer>>&& children)
504 {
505     bool childrenChanged = GraphicsLayer::setChildren(WTFMove(children));
506     if (childrenChanged)
507         noteSublayersChanged();
508     
509     return childrenChanged;
510 }
511
512 void GraphicsLayerCA::addChild(Ref<GraphicsLayer>&& childLayer)
513 {
514     GraphicsLayer::addChild(WTFMove(childLayer));
515     noteSublayersChanged();
516 }
517
518 void GraphicsLayerCA::addChildAtIndex(Ref<GraphicsLayer>&& childLayer, int index)
519 {
520     GraphicsLayer::addChildAtIndex(WTFMove(childLayer), index);
521     noteSublayersChanged();
522 }
523
524 void GraphicsLayerCA::addChildBelow(Ref<GraphicsLayer>&& childLayer, GraphicsLayer* sibling)
525 {
526     GraphicsLayer::addChildBelow(WTFMove(childLayer), sibling);
527     noteSublayersChanged();
528 }
529
530 void GraphicsLayerCA::addChildAbove(Ref<GraphicsLayer>&& childLayer, GraphicsLayer* sibling)
531 {
532     GraphicsLayer::addChildAbove(WTFMove(childLayer), sibling);
533     noteSublayersChanged();
534 }
535
536 bool GraphicsLayerCA::replaceChild(GraphicsLayer* oldChild, Ref<GraphicsLayer>&& newChild)
537 {
538     if (GraphicsLayer::replaceChild(oldChild, WTFMove(newChild))) {
539         noteSublayersChanged();
540         return true;
541     }
542     return false;
543 }
544
545 void GraphicsLayerCA::removeFromParent()
546 {
547     if (m_parent)
548         downcast<GraphicsLayerCA>(*m_parent).noteSublayersChanged();
549     GraphicsLayer::removeFromParent();
550 }
551
552 void GraphicsLayerCA::setMaskLayer(RefPtr<GraphicsLayer>&& layer)
553 {
554     if (layer == m_maskLayer)
555         return;
556
557     GraphicsLayer::setMaskLayer(WTFMove(layer));
558     noteLayerPropertyChanged(MaskLayerChanged);
559
560     propagateLayerChangeToReplicas();
561     
562     if (m_replicatedLayer)
563         downcast<GraphicsLayerCA>(*m_replicatedLayer).propagateLayerChangeToReplicas();
564 }
565
566 void GraphicsLayerCA::setReplicatedLayer(GraphicsLayer* layer)
567 {
568     if (layer == m_replicatedLayer)
569         return;
570
571     GraphicsLayer::setReplicatedLayer(layer);
572     noteLayerPropertyChanged(ReplicatedLayerChanged);
573 }
574
575 void GraphicsLayerCA::setReplicatedByLayer(RefPtr<GraphicsLayer>&& layer)
576 {
577     if (layer == m_replicaLayer)
578         return;
579
580     GraphicsLayer::setReplicatedByLayer(WTFMove(layer));
581     noteSublayersChanged();
582     noteLayerPropertyChanged(ReplicatedLayerChanged);
583 }
584
585 void GraphicsLayerCA::setPosition(const FloatPoint& point)
586 {
587     if (point == m_position)
588         return;
589
590     GraphicsLayer::setPosition(point);
591     noteLayerPropertyChanged(GeometryChanged);
592 }
593
594 void GraphicsLayerCA::syncPosition(const FloatPoint& point)
595 {
596     if (point == m_position)
597         return;
598
599     GraphicsLayer::syncPosition(point);
600     // Ensure future flushes will recompute the coverage rect and update tiling.
601     noteLayerPropertyChanged(NeedsComputeVisibleAndCoverageRect, DontScheduleFlush);
602 }
603
604 void GraphicsLayerCA::setApproximatePosition(const FloatPoint& point)
605 {
606     if (point == m_approximatePosition)
607         return;
608
609     GraphicsLayer::setApproximatePosition(point);
610     // Ensure future flushes will recompute the coverage rect and update tiling.
611     noteLayerPropertyChanged(NeedsComputeVisibleAndCoverageRect, DontScheduleFlush);
612 }
613
614 void GraphicsLayerCA::setAnchorPoint(const FloatPoint3D& point)
615 {
616     if (point == m_anchorPoint)
617         return;
618
619     GraphicsLayer::setAnchorPoint(point);
620     noteLayerPropertyChanged(GeometryChanged);
621 }
622
623 void GraphicsLayerCA::setSize(const FloatSize& size)
624 {
625     if (size == m_size)
626         return;
627
628     GraphicsLayer::setSize(size);
629     noteLayerPropertyChanged(GeometryChanged);
630 }
631
632 void GraphicsLayerCA::setBoundsOrigin(const FloatPoint& origin)
633 {
634     if (origin == m_boundsOrigin)
635         return;
636
637     GraphicsLayer::setBoundsOrigin(origin);
638     noteLayerPropertyChanged(GeometryChanged);
639 }
640
641 void GraphicsLayerCA::syncBoundsOrigin(const FloatPoint& origin)
642 {
643     if (origin == m_boundsOrigin)
644         return;
645
646     GraphicsLayer::syncBoundsOrigin(origin);
647     noteLayerPropertyChanged(NeedsComputeVisibleAndCoverageRect, DontScheduleFlush);
648 }
649
650 void GraphicsLayerCA::setTransform(const TransformationMatrix& t)
651 {
652     if (t == transform())
653         return;
654
655     GraphicsLayer::setTransform(t);
656     noteLayerPropertyChanged(TransformChanged);
657 }
658
659 void GraphicsLayerCA::setChildrenTransform(const TransformationMatrix& t)
660 {
661     if (t == childrenTransform())
662         return;
663
664     GraphicsLayer::setChildrenTransform(t);
665     noteLayerPropertyChanged(ChildrenTransformChanged);
666 }
667
668 void GraphicsLayerCA::moveOrCopyLayerAnimation(MoveOrCopy operation, const String& animationIdentifier, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
669 {
670     RefPtr<PlatformCAAnimation> anim = fromLayer->animationForKey(animationIdentifier);
671     if (!anim)
672         return;
673
674     switch (operation) {
675     case Move:
676         fromLayer->removeAnimationForKey(animationIdentifier);
677         toLayer->addAnimationForKey(animationIdentifier, *anim);
678         break;
679
680     case Copy:
681         toLayer->addAnimationForKey(animationIdentifier, *anim);
682         break;
683     }
684 }
685
686 void GraphicsLayerCA::moveOrCopyAnimations(MoveOrCopy operation, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
687 {
688     if (!hasAnimations())
689         return;
690
691     // Look for running animations affecting this property.
692     for (const auto& it : m_animations->runningAnimations) {
693         const auto& propertyAnimations = it.value;
694         size_t numAnimations = propertyAnimations.size();
695         for (size_t i = 0; i < numAnimations; ++i) {
696             const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
697
698             if (currAnimation.m_property == AnimatedPropertyTransform
699                 || currAnimation.m_property == AnimatedPropertyOpacity
700                 || currAnimation.m_property == AnimatedPropertyBackgroundColor
701                 || currAnimation.m_property == AnimatedPropertyFilter)
702                 moveOrCopyLayerAnimation(operation, animationIdentifier(currAnimation.m_name, currAnimation.m_property, currAnimation.m_index, currAnimation.m_subIndex), fromLayer, toLayer);
703         }
704     }
705 }
706
707 void GraphicsLayerCA::setPreserves3D(bool preserves3D)
708 {
709     if (preserves3D == m_preserves3D)
710         return;
711
712     GraphicsLayer::setPreserves3D(preserves3D);
713     noteLayerPropertyChanged(Preserves3DChanged);
714 }
715
716 void GraphicsLayerCA::setMasksToBounds(bool masksToBounds)
717 {
718     if (masksToBounds == m_masksToBounds)
719         return;
720
721     GraphicsLayer::setMasksToBounds(masksToBounds);
722     noteLayerPropertyChanged(MasksToBoundsChanged | DebugIndicatorsChanged);
723 }
724
725 void GraphicsLayerCA::setDrawsContent(bool drawsContent)
726 {
727     if (drawsContent == m_drawsContent)
728         return;
729
730     GraphicsLayer::setDrawsContent(drawsContent);
731     noteLayerPropertyChanged(DrawsContentChanged | DebugIndicatorsChanged);
732 }
733
734 void GraphicsLayerCA::setContentsVisible(bool contentsVisible)
735 {
736     if (contentsVisible == m_contentsVisible)
737         return;
738
739     GraphicsLayer::setContentsVisible(contentsVisible);
740     noteLayerPropertyChanged(ContentsVisibilityChanged);
741     // Visibility affects whether the contentsLayer is parented.
742     if (m_contentsLayer)
743         noteSublayersChanged();
744 }
745
746 void GraphicsLayerCA::setUserInteractionEnabled(bool userInteractionEnabled)
747 {
748     if (userInteractionEnabled == m_userInteractionEnabled)
749         return;
750     
751     GraphicsLayer::setUserInteractionEnabled(userInteractionEnabled);
752     noteLayerPropertyChanged(UserInteractionEnabledChanged);
753 }
754
755 void GraphicsLayerCA::setAcceleratesDrawing(bool acceleratesDrawing)
756 {
757     if (acceleratesDrawing == m_acceleratesDrawing)
758         return;
759
760     GraphicsLayer::setAcceleratesDrawing(acceleratesDrawing);
761     noteLayerPropertyChanged(AcceleratesDrawingChanged);
762 }
763
764 void GraphicsLayerCA::setUsesDisplayListDrawing(bool usesDisplayListDrawing)
765 {
766     if (usesDisplayListDrawing == m_usesDisplayListDrawing)
767         return;
768
769     setNeedsDisplay();
770     GraphicsLayer::setUsesDisplayListDrawing(usesDisplayListDrawing);
771 }
772
773 void GraphicsLayerCA::setBackgroundColor(const Color& color)
774 {
775     if (m_backgroundColor == color)
776         return;
777
778     GraphicsLayer::setBackgroundColor(color);
779     noteLayerPropertyChanged(BackgroundColorChanged);
780 }
781
782 void GraphicsLayerCA::setContentsOpaque(bool opaque)
783 {
784     if (m_contentsOpaque == opaque)
785         return;
786
787     GraphicsLayer::setContentsOpaque(opaque);
788     noteLayerPropertyChanged(ContentsOpaqueChanged);
789 }
790
791 void GraphicsLayerCA::setSupportsSubpixelAntialiasedText(bool supportsSubpixelAntialiasedText)
792 {
793     if (m_supportsSubpixelAntialiasedText == supportsSubpixelAntialiasedText)
794         return;
795
796     GraphicsLayer::setSupportsSubpixelAntialiasedText(supportsSubpixelAntialiasedText);
797     noteLayerPropertyChanged(SupportsSubpixelAntialiasedTextChanged);
798 }
799
800 void GraphicsLayerCA::setBackfaceVisibility(bool visible)
801 {
802     if (m_backfaceVisibility == visible)
803         return;
804     
805     GraphicsLayer::setBackfaceVisibility(visible);
806     noteLayerPropertyChanged(BackfaceVisibilityChanged);
807 }
808
809 void GraphicsLayerCA::setOpacity(float opacity)
810 {
811     float clampedOpacity = std::max(0.0f, std::min(opacity, 1.0f));
812
813     if (clampedOpacity == m_opacity)
814         return;
815
816     GraphicsLayer::setOpacity(clampedOpacity);
817     noteLayerPropertyChanged(OpacityChanged);
818 }
819
820 bool GraphicsLayerCA::setFilters(const FilterOperations& filterOperations)
821 {
822     bool canCompositeFilters = filtersCanBeComposited(filterOperations);
823
824     if (m_filters == filterOperations)
825         return canCompositeFilters;
826
827     // Filters cause flattening, so we should never have filters on a layer with preserves3D().
828     ASSERT(!filterOperations.size() || !preserves3D());
829
830     if (canCompositeFilters) {
831         GraphicsLayer::setFilters(filterOperations);
832         noteLayerPropertyChanged(FiltersChanged);
833     } else if (filters().size()) {
834         // In this case filters are rendered in software, so we need to remove any 
835         // previously attached hardware filters.
836         clearFilters();
837         noteLayerPropertyChanged(FiltersChanged);
838     }
839     return canCompositeFilters;
840 }
841
842 bool GraphicsLayerCA::setBackdropFilters(const FilterOperations& filterOperations)
843 {
844     bool canCompositeFilters = filtersCanBeComposited(filterOperations);
845
846     if (m_backdropFilters == filterOperations)
847         return canCompositeFilters;
848
849     // Filters cause flattening, so we should never have filters on a layer with preserves3D().
850     ASSERT(!filterOperations.size() || !preserves3D());
851
852     if (canCompositeFilters)
853         GraphicsLayer::setBackdropFilters(filterOperations);
854     else {
855         // FIXME: This would clear the backdrop filters if we had a software implementation.
856         clearBackdropFilters();
857     }
858
859     noteLayerPropertyChanged(BackdropFiltersChanged | DebugIndicatorsChanged);
860     return canCompositeFilters;
861 }
862
863 void GraphicsLayerCA::setBackdropFiltersRect(const FloatRoundedRect& backdropFiltersRect)
864 {
865     if (backdropFiltersRect == m_backdropFiltersRect)
866         return;
867
868     GraphicsLayer::setBackdropFiltersRect(backdropFiltersRect);
869     noteLayerPropertyChanged(BackdropFiltersRectChanged);
870 }
871
872 #if ENABLE(CSS_COMPOSITING)
873 void GraphicsLayerCA::setBlendMode(BlendMode blendMode)
874 {
875     if (GraphicsLayer::blendMode() == blendMode)
876         return;
877
878     GraphicsLayer::setBlendMode(blendMode);
879     noteLayerPropertyChanged(BlendModeChanged);
880 }
881 #endif
882
883 bool GraphicsLayerCA::backingStoreAttached() const
884 {
885     return m_layer->backingStoreAttached();
886 }
887
888 bool GraphicsLayerCA::backingStoreAttachedForTesting() const
889 {
890     return m_layer->backingStoreAttached() || m_layer->hasContents();
891 }
892
893 void GraphicsLayerCA::setNeedsDisplay()
894 {
895     if (!drawsContent())
896         return;
897
898     m_needsFullRepaint = true;
899     m_dirtyRects.clear();
900     noteLayerPropertyChanged(DirtyRectsChanged);
901     addRepaintRect(FloatRect(FloatPoint(), m_size));
902 }
903
904 void GraphicsLayerCA::setNeedsDisplayInRect(const FloatRect& r, ShouldClipToLayer shouldClip)
905 {
906     if (!drawsContent())
907         return;
908
909     if (m_needsFullRepaint)
910         return;
911
912     FloatRect rect(r);
913     if (shouldClip == ClipToLayer) {
914         FloatRect layerBounds(FloatPoint(), m_size);
915         rect.intersect(layerBounds);
916     }
917
918     if (rect.isEmpty())
919         return;
920
921     addRepaintRect(rect);
922
923     const size_t maxDirtyRects = 32;
924
925     for (size_t i = 0; i < m_dirtyRects.size(); ++i) {
926         if (m_dirtyRects[i].contains(rect))
927             return;
928     }
929
930     if (m_dirtyRects.size() < maxDirtyRects)
931         m_dirtyRects.append(rect);
932     else
933         m_dirtyRects[0].unite(rect);
934
935     noteLayerPropertyChanged(DirtyRectsChanged);
936 }
937
938 void GraphicsLayerCA::setContentsNeedsDisplay()
939 {
940     noteLayerPropertyChanged(ContentsNeedsDisplay);
941 }
942
943 void GraphicsLayerCA::setContentsRect(const FloatRect& rect)
944 {
945     if (rect == m_contentsRect)
946         return;
947
948     GraphicsLayer::setContentsRect(rect);
949     noteLayerPropertyChanged(ContentsRectsChanged);
950 }
951
952 void GraphicsLayerCA::setContentsClippingRect(const FloatRoundedRect& rect)
953 {
954     if (rect == m_contentsClippingRect)
955         return;
956
957     GraphicsLayer::setContentsClippingRect(rect);
958     noteLayerPropertyChanged(ContentsRectsChanged);
959 }
960
961 bool GraphicsLayerCA::setMasksToBoundsRect(const FloatRoundedRect& roundedRect)
962 {
963     if (roundedRect == m_masksToBoundsRect)
964         return true;
965
966     GraphicsLayer::setMasksToBoundsRect(roundedRect);
967     noteLayerPropertyChanged(MasksToBoundsRectChanged);
968     return true;
969 }
970
971 void GraphicsLayerCA::setShapeLayerPath(const Path& path)
972 {
973     // FIXME: need to check for path equality. No bool Path::operator==(const Path&)!.
974     GraphicsLayer::setShapeLayerPath(path);
975     noteLayerPropertyChanged(ShapeChanged);
976 }
977
978 void GraphicsLayerCA::setShapeLayerWindRule(WindRule windRule)
979 {
980     if (windRule == m_shapeLayerWindRule)
981         return;
982
983     GraphicsLayer::setShapeLayerWindRule(windRule);
984     noteLayerPropertyChanged(WindRuleChanged);
985 }
986
987 void GraphicsLayerCA::setEventRegion(EventRegion&& eventRegion)
988 {
989     if (eventRegion == m_eventRegion)
990         return;
991
992     GraphicsLayer::setEventRegion(WTFMove(eventRegion));
993     noteLayerPropertyChanged(EventRegionChanged, m_isCommittingChanges ? DontScheduleFlush : ScheduleFlush);
994 }
995
996 bool GraphicsLayerCA::shouldRepaintOnSizeChange() const
997 {
998     return drawsContent() && !tiledBacking();
999 }
1000
1001 bool GraphicsLayerCA::animationCanBeAccelerated(const KeyframeValueList& valueList, const Animation* anim) const
1002 {
1003     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
1004         return false;
1005
1006     if (animationHasStepsTimingFunction(valueList, anim))
1007         return false;
1008
1009     return true;
1010 }
1011
1012 void GraphicsLayerCA::addProcessingActionForAnimation(const String& animationName, AnimationProcessingAction processingAction)
1013 {
1014     ensureLayerAnimations();
1015
1016     auto& processingActions = m_animations->animationsToProcess.ensure(animationName, [] {
1017         return Vector<AnimationProcessingAction> { };
1018     }).iterator->value;
1019
1020     if (!processingActions.isEmpty() && processingActions.last().action == Remove)
1021         return;
1022
1023     processingActions.append(processingAction);
1024 }
1025
1026 bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const FloatSize& boxSize, const Animation* anim, const String& animationName, double timeOffset)
1027 {
1028     LOG(Animations, "GraphicsLayerCA %p %llu addAnimation %s (can be accelerated %d)", this, primaryLayerID(), animationName.utf8().data(), animationCanBeAccelerated(valueList, anim));
1029
1030     ASSERT(!animationName.isEmpty());
1031
1032     if (!animationCanBeAccelerated(valueList, anim))
1033         return false;
1034
1035     bool createdAnimations = false;
1036     if (valueList.property() == AnimatedPropertyTransform)
1037         createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, animationName, Seconds { timeOffset }, boxSize);
1038     else if (valueList.property() == AnimatedPropertyFilter) {
1039         if (supportsAcceleratedFilterAnimations())
1040             createdAnimations = createFilterAnimationsFromKeyframes(valueList, anim, animationName, Seconds { timeOffset });
1041     }
1042 #if ENABLE(FILTERS_LEVEL_2)
1043     else if (valueList.property() == AnimatedPropertyWebkitBackdropFilter) {
1044         if (supportsAcceleratedFilterAnimations())
1045             createdAnimations = createFilterAnimationsFromKeyframes(valueList, anim, animationName, Seconds { timeOffset });
1046     }
1047 #endif
1048     else
1049         createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, Seconds { timeOffset });
1050
1051     if (createdAnimations)
1052         noteLayerPropertyChanged(AnimationChanged | CoverageRectChanged);
1053
1054     return createdAnimations;
1055 }
1056
1057 void GraphicsLayerCA::pauseAnimation(const String& animationName, double timeOffset)
1058 {
1059     LOG(Animations, "GraphicsLayerCA %p pauseAnimation %s (running %d)", this, animationName.utf8().data(), animationIsRunning(animationName));
1060
1061     // Call add since if there is already a Remove in there, we don't want to overwrite it with a Pause.
1062     addProcessingActionForAnimation(animationName, AnimationProcessingAction { Pause, Seconds { timeOffset } });
1063
1064     noteLayerPropertyChanged(AnimationChanged);
1065 }
1066
1067 void GraphicsLayerCA::seekAnimation(const String& animationName, double timeOffset)
1068 {
1069     LOG(Animations, "GraphicsLayerCA %p seekAnimation %s (running %d)", this, animationName.utf8().data(), animationIsRunning(animationName));
1070
1071     // Call add since if there is already a Remove in there, we don't want to overwrite it with a Pause.
1072     addProcessingActionForAnimation(animationName, AnimationProcessingAction { Seek, Seconds { timeOffset } });
1073
1074     noteLayerPropertyChanged(AnimationChanged);
1075 }
1076
1077 void GraphicsLayerCA::removeAnimation(const String& animationName)
1078 {
1079     LOG(Animations, "GraphicsLayerCA %p removeAnimation %s (running %d)", this, animationName.utf8().data(), animationIsRunning(animationName));
1080
1081     if (!animationIsRunning(animationName))
1082         return;
1083
1084     addProcessingActionForAnimation(animationName, AnimationProcessingAction(Remove));
1085     noteLayerPropertyChanged(AnimationChanged | CoverageRectChanged);
1086 }
1087
1088 void GraphicsLayerCA::platformCALayerAnimationStarted(const String& animationKey, MonotonicTime startTime)
1089 {
1090     LOG(Animations, "GraphicsLayerCA %p platformCALayerAnimationStarted %s at %f", this, animationKey.utf8().data(), startTime.secondsSinceEpoch().seconds());
1091     client().notifyAnimationStarted(this, animationKey, startTime);
1092 }
1093
1094 void GraphicsLayerCA::platformCALayerAnimationEnded(const String& animationKey)
1095 {
1096     LOG(Animations, "GraphicsLayerCA %p platformCALayerAnimationEnded %s", this, animationKey.utf8().data());
1097     client().notifyAnimationEnded(this, animationKey);
1098 }
1099
1100 void GraphicsLayerCA::setContentsToSolidColor(const Color& color)
1101 {
1102     if (color == m_contentsSolidColor)
1103         return;
1104
1105     m_contentsSolidColor = color;
1106     
1107     bool contentsLayerChanged = false;
1108
1109     if (m_contentsSolidColor.isVisible()) {
1110         if (!m_contentsLayer || m_contentsLayerPurpose != ContentsLayerPurpose::BackgroundColor) {
1111             m_contentsLayerPurpose = ContentsLayerPurpose::BackgroundColor;
1112             m_contentsLayer = createPlatformCALayer(PlatformCALayer::LayerTypeLayer, this);
1113 #if ENABLE(TREE_DEBUGGING)
1114             m_contentsLayer->setName(makeString("contents color ", m_contentsLayer->layerID()));
1115 #else
1116             m_contentsLayer->setName("contents color");
1117 #endif
1118             contentsLayerChanged = true;
1119         }
1120     } else {
1121         contentsLayerChanged = m_contentsLayer;
1122         m_contentsLayerPurpose = ContentsLayerPurpose::None;
1123         m_contentsLayer = nullptr;
1124     }
1125
1126     if (contentsLayerChanged)
1127         noteSublayersChanged();
1128
1129     noteLayerPropertyChanged(ContentsColorLayerChanged);
1130 }
1131
1132 void GraphicsLayerCA::setContentsToImage(Image* image)
1133 {
1134     if (image) {
1135         auto newImage = image->nativeImageForCurrentFrame();
1136         if (!newImage)
1137             return;
1138
1139         // FIXME: probably don't need m_uncorrectedContentsImage at all now.
1140         if (m_uncorrectedContentsImage == newImage)
1141             return;
1142         
1143         m_uncorrectedContentsImage = WTFMove(newImage);
1144         m_pendingContentsImage = m_uncorrectedContentsImage;
1145
1146         m_contentsLayerPurpose = ContentsLayerPurpose::Image;
1147         if (!m_contentsLayer)
1148             noteSublayersChanged();
1149     } else {
1150         m_uncorrectedContentsImage = nullptr;
1151         m_pendingContentsImage = nullptr;
1152         m_contentsLayerPurpose = ContentsLayerPurpose::None;
1153         if (m_contentsLayer)
1154             noteSublayersChanged();
1155     }
1156
1157     noteLayerPropertyChanged(ContentsImageChanged);
1158 }
1159
1160 void GraphicsLayerCA::setContentsToEmbeddedView(GraphicsLayer::ContentsLayerEmbeddedViewType layerType, GraphicsLayer::EmbeddedViewID embeddedViewID)
1161 {
1162     bool contentsLayerChanged = false;
1163
1164     if (layerType != GraphicsLayer::ContentsLayerEmbeddedViewType::None) {
1165         m_contentsLayerPurpose = ContentsLayerPurpose::EmbeddedView;
1166
1167         PlatformCALayer::LayerType platformType;
1168         switch (layerType) {
1169         case GraphicsLayer::ContentsLayerEmbeddedViewType::EditableImage:
1170             platformType = PlatformCALayer::LayerTypeEditableImageLayer;
1171             break;
1172         default:
1173             ASSERT_NOT_REACHED();
1174             platformType = PlatformCALayer::LayerTypeLayer;
1175             break;
1176         }
1177
1178         if (!m_contentsLayer || m_contentsLayer->layerType() != platformType || m_contentsLayer->embeddedViewID() != embeddedViewID) {
1179             m_contentsLayer = createPlatformCALayerForEmbeddedView(platformType, embeddedViewID, this);
1180             m_contentsLayer->setAnchorPoint(FloatPoint3D());
1181             contentsLayerChanged = true;
1182         }
1183     } else {
1184         m_contentsLayerPurpose = ContentsLayerPurpose::None;
1185         contentsLayerChanged = m_contentsLayer;
1186         m_contentsLayer = nullptr;
1187     }
1188
1189     if (contentsLayerChanged)
1190         noteSublayersChanged();
1191 }
1192
1193 void GraphicsLayerCA::setContentsToPlatformLayer(PlatformLayer* platformLayer, ContentsLayerPurpose purpose)
1194 {
1195     if (m_contentsLayer && platformLayer == m_contentsLayer->platformLayer())
1196         return;
1197
1198     if (m_contentsClippingLayer && m_contentsLayer)
1199         m_contentsLayer->removeFromSuperlayer();
1200
1201     // FIXME: The passed in layer might be a raw layer or an externally created
1202     // PlatformCALayer. To determine this we attempt to get the
1203     // PlatformCALayer pointer. If this returns a null pointer we assume it's
1204     // raw. This test might be invalid if the raw layer is, for instance, the
1205     // PlatformCALayer is using a user data pointer in the raw layer, and
1206     // the creator of the raw layer is using it for some other purpose.
1207     // For now we don't support such a case.
1208     PlatformCALayer* platformCALayer = PlatformCALayer::platformCALayer(platformLayer);
1209     m_contentsLayer = platformLayer ? (platformCALayer ? platformCALayer : createPlatformCALayer(platformLayer, this).ptr()) : nullptr;
1210     m_contentsLayerPurpose = platformLayer ? purpose : ContentsLayerPurpose::None;
1211
1212     if (m_contentsClippingLayer && m_contentsLayer)
1213         m_contentsClippingLayer->appendSublayer(*m_contentsLayer);
1214
1215     noteSublayersChanged();
1216     noteLayerPropertyChanged(ContentsPlatformLayerChanged);
1217 }
1218
1219 #if PLATFORM(IOS_FAMILY)
1220 PlatformLayer* GraphicsLayerCA::contentsLayerForMedia() const
1221 {
1222     return m_contentsLayerPurpose == ContentsLayerPurpose::Media ? m_contentsLayer->platformLayer() : nullptr;
1223 }
1224 #endif
1225
1226 void GraphicsLayerCA::layerDidDisplay(PlatformCALayer* layer)
1227 {
1228     if (!m_layerClones)
1229         return;
1230
1231     LayerMap* layerCloneMap = nullptr;
1232
1233     if (layer == m_layer)
1234         layerCloneMap = &m_layerClones->primaryLayerClones;
1235     else if (layer == m_contentsLayer)
1236         layerCloneMap = &m_layerClones->contentsLayerClones;
1237
1238     if (layerCloneMap) {
1239         for (auto& platformLayerClone : layerCloneMap->values())
1240             platformLayerClone->copyContentsFromLayer(layer);
1241     }
1242 }
1243
1244 FloatPoint GraphicsLayerCA::computePositionRelativeToBase(float& pageScale) const
1245 {
1246     pageScale = 1;
1247
1248     FloatPoint offset;
1249     for (const GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) {
1250         if (currLayer->appliesPageScale()) {
1251             pageScale = currLayer->pageScaleFactor();
1252             return offset;
1253         }
1254
1255         offset += currLayer->position();
1256     }
1257
1258     return FloatPoint();
1259 }
1260
1261 void GraphicsLayerCA::flushCompositingState(const FloatRect& visibleRect)
1262 {
1263     TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(visibleRect));
1264     FloatQuad coverageQuad(visibleRect);
1265     state.setSecondaryQuad(&coverageQuad);
1266
1267     CommitState commitState;
1268     commitState.ancestorHadChanges = visibleRect != m_previousCommittedVisibleRect;
1269     m_previousCommittedVisibleRect = visibleRect;
1270
1271 #if PLATFORM(IOS_FAMILY)
1272     // In WK1, UIKit may be changing layer bounds behind our back in overflow-scroll layers, so disable the optimization.
1273     // See the similar test in computeVisibleAndCoverageRect().
1274     if (m_layer->isPlatformCALayerCocoa())
1275         commitState.ancestorHadChanges = true;
1276 #endif
1277
1278     recursiveCommitChanges(commitState, state);
1279 }
1280
1281 void GraphicsLayerCA::flushCompositingStateForThisLayerOnly()
1282 {
1283     float pageScaleFactor;
1284     bool layerTypeChanged = false;
1285     
1286     CommitState commitState;
1287
1288     FloatPoint offset = computePositionRelativeToBase(pageScaleFactor);
1289     commitLayerChangesBeforeSublayers(commitState, pageScaleFactor, offset, layerTypeChanged);
1290     commitLayerChangesAfterSublayers(commitState);
1291
1292     if (layerTypeChanged)
1293         client().didChangePlatformLayerForLayer(this);
1294 }
1295
1296 static inline bool accumulatesTransform(const GraphicsLayerCA& layer)
1297 {
1298     return !layer.masksToBounds() && (layer.preserves3D() || (layer.parent() && layer.parent()->preserves3D()));
1299 }
1300
1301 bool GraphicsLayerCA::recursiveVisibleRectChangeRequiresFlush(const CommitState& commitState, const TransformState& state) const
1302 {
1303     TransformState localState = state;
1304     CommitState childCommitState = commitState;
1305
1306     // This may be called at times when layout has not been updated, so we want to avoid calling out to the client
1307     // for animating transforms.
1308     VisibleAndCoverageRects rects = computeVisibleAndCoverageRect(localState, accumulatesTransform(*this), 0);
1309     adjustCoverageRect(rects, m_visibleRect);
1310
1311     auto bounds = FloatRect(m_boundsOrigin, size());
1312
1313     bool isViewportConstrained = m_isViewportConstrained || commitState.ancestorIsViewportConstrained;
1314     bool intersectsCoverageRect = isViewportConstrained || rects.coverageRect.intersects(bounds);
1315     if (intersectsCoverageRect != m_intersectsCoverageRect)
1316         return true;
1317
1318     if (rects.coverageRect != m_coverageRect) {
1319         if (TiledBacking* tiledBacking = this->tiledBacking()) {
1320             if (tiledBacking->tilesWouldChangeForCoverageRect(rects.coverageRect))
1321                 return true;
1322         }
1323     }
1324
1325     childCommitState.ancestorIsViewportConstrained |= m_isViewportConstrained;
1326
1327     if (m_maskLayer) {
1328         auto& maskLayerCA = downcast<GraphicsLayerCA>(*m_maskLayer);
1329         if (maskLayerCA.recursiveVisibleRectChangeRequiresFlush(childCommitState, localState))
1330             return true;
1331     }
1332
1333     for (const auto& layer : children()) {
1334         const auto& currentChild = downcast<GraphicsLayerCA>(layer.get());
1335         if (currentChild.recursiveVisibleRectChangeRequiresFlush(childCommitState, localState))
1336             return true;
1337     }
1338
1339     if (m_replicaLayer)
1340         if (downcast<GraphicsLayerCA>(*m_replicaLayer).recursiveVisibleRectChangeRequiresFlush(childCommitState, localState))
1341             return true;
1342     
1343     return false;
1344 }
1345
1346 bool GraphicsLayerCA::visibleRectChangeRequiresFlush(const FloatRect& clipRect) const
1347 {
1348     TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(clipRect));
1349     CommitState commitState;
1350     return recursiveVisibleRectChangeRequiresFlush(commitState, state);
1351 }
1352
1353 TiledBacking* GraphicsLayerCA::tiledBacking() const
1354 {
1355     return m_layer->tiledBacking();
1356 }
1357
1358 TransformationMatrix GraphicsLayerCA::layerTransform(const FloatPoint& position, const TransformationMatrix* customTransform) const
1359 {
1360     TransformationMatrix transform;
1361     transform.translate(position.x(), position.y());
1362
1363     TransformationMatrix currentTransform;
1364     if (customTransform)
1365         currentTransform = *customTransform;
1366     else if (m_transform)
1367         currentTransform = *m_transform;
1368     
1369     if (!currentTransform.isIdentity()) {
1370         FloatPoint3D absoluteAnchorPoint(anchorPoint());
1371         absoluteAnchorPoint.scale(size().width(), size().height(), 1);
1372         transform.translate3d(absoluteAnchorPoint.x(), absoluteAnchorPoint.y(), absoluteAnchorPoint.z());
1373         transform.multiply(currentTransform);
1374         transform.translate3d(-absoluteAnchorPoint.x(), -absoluteAnchorPoint.y(), -absoluteAnchorPoint.z());
1375     }
1376
1377     if (GraphicsLayer* parentLayer = parent()) {
1378         if (parentLayer->hasNonIdentityChildrenTransform()) {
1379             FloatPoint3D parentAnchorPoint(parentLayer->anchorPoint());
1380             parentAnchorPoint.scale(parentLayer->size().width(), parentLayer->size().height(), 1);
1381
1382             transform.translateRight3d(-parentAnchorPoint.x(), -parentAnchorPoint.y(), -parentAnchorPoint.z());
1383             transform = parentLayer->childrenTransform() * transform;
1384             transform.translateRight3d(parentAnchorPoint.x(), parentAnchorPoint.y(), parentAnchorPoint.z());
1385         }
1386     }
1387     
1388     return transform;
1389 }
1390
1391 GraphicsLayerCA::VisibleAndCoverageRects GraphicsLayerCA::computeVisibleAndCoverageRect(TransformState& state, bool preserves3D, ComputeVisibleRectFlags flags) const
1392 {
1393     FloatPoint position = approximatePosition();
1394     client().customPositionForVisibleRectComputation(this, position);
1395
1396     TransformationMatrix layerTransform;
1397     TransformationMatrix currentTransform;
1398     if ((flags & RespectAnimatingTransforms) && client().getCurrentTransform(this, currentTransform))
1399         layerTransform = this->layerTransform(position, &currentTransform);
1400     else
1401         layerTransform = this->layerTransform(position);
1402
1403     bool applyWasClamped;
1404     TransformState::TransformAccumulation accumulation = preserves3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform;
1405     state.applyTransform(layerTransform, accumulation, &applyWasClamped);
1406
1407     bool mapWasClamped;
1408     FloatRect clipRectForChildren = state.mappedQuad(&mapWasClamped).boundingBox();
1409     FloatPoint boundsOrigin = m_boundsOrigin;
1410 #if PLATFORM(IOS_FAMILY)
1411     // In WK1, UIKit may be changing layer bounds behind our back in overflow-scroll layers, so use the layer's origin.
1412     if (m_layer->isPlatformCALayerCocoa())
1413         boundsOrigin = m_layer->bounds().location();
1414 #endif
1415     clipRectForChildren.move(boundsOrigin.x(), boundsOrigin.y());
1416     
1417     FloatRect clipRectForSelf(boundsOrigin, m_size);
1418     if (!applyWasClamped && !mapWasClamped)
1419         clipRectForSelf.intersect(clipRectForChildren);
1420
1421     if (masksToBounds()) {
1422         ASSERT(accumulation == TransformState::FlattenTransform);
1423         // Flatten, and replace the quad in the TransformState with one that is clipped to this layer's bounds.
1424         state.flatten();
1425         state.setQuad(clipRectForSelf);
1426         if (state.isMappingSecondaryQuad()) {
1427             FloatQuad secondaryQuad(clipRectForSelf);
1428             state.setSecondaryQuad(&secondaryQuad);
1429         }
1430     }
1431
1432     FloatRect coverageRect = clipRectForSelf;
1433     Optional<FloatQuad> quad = state.mappedSecondaryQuad(&mapWasClamped);
1434     if (quad && !mapWasClamped && !applyWasClamped)
1435         coverageRect = (*quad).boundingBox();
1436
1437     return { clipRectForSelf, coverageRect, currentTransform };
1438 }
1439
1440 bool GraphicsLayerCA::adjustCoverageRect(VisibleAndCoverageRects& rects, const FloatRect& oldVisibleRect) const
1441 {
1442     FloatRect coverageRect = rects.coverageRect;
1443
1444     // FIXME: TileController's computeTileCoverageRect() code should move here, and we should unify these different
1445     // ways of computing coverage.
1446     switch (type()) {
1447     case Type::PageTiledBacking:
1448         tiledBacking()->adjustTileCoverageRect(coverageRect, size(), oldVisibleRect, rects.visibleRect, pageScaleFactor() * deviceScaleFactor());
1449         break;
1450     case Type::Normal:
1451         if (m_layer->layerType() == PlatformCALayer::LayerTypeTiledBackingLayer)
1452             coverageRect.unite(adjustTiledLayerVisibleRect(tiledBacking(), oldVisibleRect, rects.visibleRect, m_sizeAtLastCoverageRectUpdate, m_size));
1453         break;
1454     default:
1455         break;
1456     }
1457     
1458     if (rects.coverageRect == coverageRect)
1459         return false;
1460
1461     rects.coverageRect = coverageRect;
1462     return true;
1463 }
1464
1465 void GraphicsLayerCA::setVisibleAndCoverageRects(const VisibleAndCoverageRects& rects, bool isViewportConstrained)
1466 {
1467     bool visibleRectChanged = rects.visibleRect != m_visibleRect;
1468     bool coverageRectChanged = rects.coverageRect != m_coverageRect;
1469     if (!visibleRectChanged && !coverageRectChanged && !animationExtent())
1470         return;
1471
1472     auto bounds = FloatRect(m_boundsOrigin, size());
1473     if (auto extent = animationExtent()) {
1474         // Adjust the animation extent to match the current animation position.
1475         bounds = rects.animatingTransform.inverse().valueOr(TransformationMatrix()).mapRect(*extent);
1476     }
1477
1478     // FIXME: we need to take reflections into account when determining whether this layer intersects the coverage rect.
1479     bool intersectsCoverageRect = isViewportConstrained || rects.coverageRect.intersects(bounds);
1480     if (intersectsCoverageRect != m_intersectsCoverageRect) {
1481         addUncommittedChanges(CoverageRectChanged);
1482         m_intersectsCoverageRect = intersectsCoverageRect;
1483     }
1484
1485     if (visibleRectChanged) {
1486         addUncommittedChanges(CoverageRectChanged);
1487         m_visibleRect = rects.visibleRect;
1488     }
1489
1490     if (coverageRectChanged) {
1491         addUncommittedChanges(CoverageRectChanged);
1492         m_coverageRect = rects.coverageRect;
1493     }
1494 }
1495
1496 bool GraphicsLayerCA::needsCommit(const CommitState& commitState)
1497 {
1498     if (commitState.ancestorHadChanges)
1499         return true;
1500     if (m_uncommittedChanges)
1501         return true;
1502     if (hasDescendantsWithUncommittedChanges())
1503         return true;
1504     // Accelerated transforms move the underlying layers without GraphicsLayers getting invalidated.
1505     if (isRunningTransformAnimation())
1506         return true;
1507     if (hasDescendantsWithRunningTransformAnimations())
1508         return true;
1509
1510     return false;
1511 }
1512
1513 // rootRelativeTransformForScaling is a transform from the root, but for layers with transform animations, it cherry-picked the state of the
1514 // animation that contributes maximally to the scale (on every layer with animations down the hierarchy).
1515 void GraphicsLayerCA::recursiveCommitChanges(CommitState& commitState, const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
1516 {
1517     if (!needsCommit(commitState))
1518         return;
1519
1520     TransformState localState = state;
1521     CommitState childCommitState = commitState;
1522
1523     bool affectedByTransformAnimation = commitState.ancestorHasTransformAnimation;
1524
1525     bool accumulateTransform = accumulatesTransform(*this);
1526     VisibleAndCoverageRects rects = computeVisibleAndCoverageRect(localState, accumulateTransform);
1527     if (adjustCoverageRect(rects, m_visibleRect)) {
1528         if (state.isMappingSecondaryQuad()) {
1529             FloatQuad secondaryQuad(rects.coverageRect);
1530             localState.setLastPlanarSecondaryQuad(&secondaryQuad);
1531         }
1532     }
1533     setVisibleAndCoverageRects(rects, m_isViewportConstrained || commitState.ancestorIsViewportConstrained);
1534
1535     if (commitState.ancestorStartedOrEndedTransformAnimation)
1536         addUncommittedChanges(CoverageRectChanged);
1537
1538 #ifdef VISIBLE_TILE_WASH
1539     // Use having a transform as a key to making the tile wash layer. If every layer gets a wash,
1540     // they start to obscure useful information.
1541     if ((!m_transform.isIdentity() || tiledBacking()) && !m_visibleTileWashLayer) {
1542         static NeverDestroyed<Color> washFillColor(255, 0, 0, 50);
1543         static NeverDestroyed<Color> washBorderColor(255, 0, 0, 100);
1544         
1545         m_visibleTileWashLayer = createPlatformCALayer(PlatformCALayer::LayerTypeLayer, this);
1546         String name = makeString("Visible Tile Wash Layer 0x", hex(reinterpret_cast<uintptr_t>(m_visibleTileWashLayer->platformLayer()), Lowercase));
1547         m_visibleTileWashLayer->setName(name);
1548         m_visibleTileWashLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
1549         m_visibleTileWashLayer->setBorderColor(washBorderColor);
1550         m_visibleTileWashLayer->setBorderWidth(8);
1551         m_visibleTileWashLayer->setBackgroundColor(washFillColor);
1552         noteSublayersChanged(DontScheduleFlush);
1553     }
1554
1555     if (m_visibleTileWashLayer) {
1556         m_visibleTileWashLayer->setPosition(m_visibleRect.location());
1557         m_visibleTileWashLayer->setBounds(FloatRect(FloatPoint(), m_visibleRect.size()));
1558     }
1559 #endif
1560
1561     bool hadChanges = m_uncommittedChanges;
1562
1563     // FIXME: This could be more fine-grained. Only some types of changes have impact on sublayers.
1564     if (!childCommitState.ancestorHadChanges)
1565         childCommitState.ancestorHadChanges = hadChanges;
1566
1567     if (appliesPageScale()) {
1568         pageScaleFactor = this->pageScaleFactor();
1569         affectedByPageScale = true;
1570     }
1571
1572     // Accumulate an offset from the ancestral pixel-aligned layer.
1573     FloatPoint baseRelativePosition = positionRelativeToBase;
1574     if (affectedByPageScale)
1575         baseRelativePosition += m_position;
1576
1577     bool wasRunningTransformAnimation = isRunningTransformAnimation();
1578     bool layerTypeChanged = false;
1579     
1580     commitLayerChangesBeforeSublayers(childCommitState, pageScaleFactor, baseRelativePosition, layerTypeChanged);
1581
1582     bool nowRunningTransformAnimation = wasRunningTransformAnimation;
1583     if (m_uncommittedChanges & AnimationChanged)
1584         nowRunningTransformAnimation = isRunningTransformAnimation();
1585
1586     if (wasRunningTransformAnimation != nowRunningTransformAnimation)
1587         childCommitState.ancestorStartedOrEndedTransformAnimation = true;
1588
1589     if (nowRunningTransformAnimation) {
1590         childCommitState.ancestorHasTransformAnimation = true;
1591         if (m_intersectsCoverageRect || !animationExtent())
1592             childCommitState.ancestorWithTransformAnimationIntersectsCoverageRect = true;
1593         affectedByTransformAnimation = true;
1594     }
1595     
1596     childCommitState.ancestorIsViewportConstrained |= m_isViewportConstrained;
1597
1598     if (GraphicsLayerCA* maskLayer = downcast<GraphicsLayerCA>(m_maskLayer.get())) {
1599         maskLayer->setVisibleAndCoverageRects(rects, m_isViewportConstrained || commitState.ancestorIsViewportConstrained);
1600         maskLayer->commitLayerChangesBeforeSublayers(childCommitState, pageScaleFactor, baseRelativePosition, layerTypeChanged);
1601     }
1602
1603     bool hasDescendantsWithRunningTransformAnimations = false;
1604     
1605     for (auto& layer : children()) {
1606         auto& currentChild = downcast<GraphicsLayerCA>(layer.get());
1607         currentChild.recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
1608
1609         if (currentChild.isRunningTransformAnimation() || currentChild.hasDescendantsWithRunningTransformAnimations())
1610             hasDescendantsWithRunningTransformAnimations = true;
1611     }
1612
1613     commitState.totalBackdropFilterArea = childCommitState.totalBackdropFilterArea;
1614
1615     if (GraphicsLayerCA* replicaLayer = downcast<GraphicsLayerCA>(m_replicaLayer.get()))
1616         replicaLayer->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
1617
1618     if (GraphicsLayerCA* maskLayer = downcast<GraphicsLayerCA>(m_maskLayer.get()))
1619         maskLayer->commitLayerChangesAfterSublayers(childCommitState);
1620
1621     setHasDescendantsWithUncommittedChanges(false);
1622     setHasDescendantsWithRunningTransformAnimations(hasDescendantsWithRunningTransformAnimations);
1623
1624     bool hadDirtyRects = m_uncommittedChanges & DirtyRectsChanged;
1625     commitLayerChangesAfterSublayers(childCommitState);
1626
1627     if (affectedByTransformAnimation && m_layer->layerType() == PlatformCALayer::LayerTypeTiledBackingLayer)
1628         client().notifyFlushBeforeDisplayRefresh(this);
1629
1630     if (layerTypeChanged)
1631         client().didChangePlatformLayerForLayer(this);
1632
1633     if (usesDisplayListDrawing() && m_drawsContent && (!m_hasEverPainted || hadDirtyRects)) {
1634         TraceScope tracingScope(DisplayListRecordStart, DisplayListRecordEnd);
1635
1636         m_displayList = std::make_unique<DisplayList::DisplayList>();
1637         
1638         FloatRect initialClip(boundsOrigin(), size());
1639
1640         GraphicsContext context([&](GraphicsContext& context) {
1641             return std::make_unique<DisplayList::Recorder>(context, *m_displayList, GraphicsContextState(), initialClip, AffineTransform());
1642         });
1643         paintGraphicsLayerContents(context, FloatRect(FloatPoint(), size()));
1644     }
1645 }
1646
1647 void GraphicsLayerCA::platformCALayerCustomSublayersChanged(PlatformCALayer*)
1648 {
1649     noteLayerPropertyChanged(ChildrenChanged, m_isCommittingChanges ? DontScheduleFlush : ScheduleFlush);
1650 }
1651
1652 bool GraphicsLayerCA::platformCALayerShowRepaintCounter(PlatformCALayer* platformLayer) const
1653 {
1654     // The repaint counters are painted into the TileController tiles (which have no corresponding platform layer),
1655     // so we don't want to overpaint the repaint counter when called with the TileController's own layer.
1656     if (isPageTiledBackingLayer() && platformLayer)
1657         return false;
1658
1659     return isShowingRepaintCounter();
1660 }
1661
1662 void GraphicsLayerCA::platformCALayerPaintContents(PlatformCALayer*, GraphicsContext& context, const FloatRect& clip, GraphicsLayerPaintBehavior layerPaintBehavior)
1663 {
1664     m_hasEverPainted = true;
1665     if (m_displayList) {
1666         DisplayList::Replayer replayer(context, *m_displayList);
1667         
1668         if (UNLIKELY(isTrackingDisplayListReplay())) {
1669             auto replayList = replayer.replay(clip, isTrackingDisplayListReplay());
1670             layerDisplayListMap().add(this, std::pair<FloatRect, std::unique_ptr<DisplayList::DisplayList>>(clip, WTFMove(replayList)));
1671         } else
1672             replayer.replay(clip);
1673
1674         return;
1675     }
1676
1677     TraceScope tracingScope(PaintLayerStart, PaintLayerEnd);
1678     paintGraphicsLayerContents(context, clip, layerPaintBehavior);
1679 }
1680
1681 void GraphicsLayerCA::platformCALayerSetNeedsToRevalidateTiles()
1682 {
1683     noteLayerPropertyChanged(TilingAreaChanged, m_isCommittingChanges ? DontScheduleFlush : ScheduleFlush);
1684 }
1685
1686 float GraphicsLayerCA::platformCALayerDeviceScaleFactor() const
1687 {
1688     return deviceScaleFactor();
1689 }
1690
1691 float GraphicsLayerCA::platformCALayerContentsScaleMultiplierForNewTiles(PlatformCALayer*) const
1692 {
1693     return client().contentsScaleMultiplierForNewTiles(this);
1694 }
1695
1696 bool GraphicsLayerCA::platformCALayerShouldAggressivelyRetainTiles(PlatformCALayer*) const
1697 {
1698     return client().shouldAggressivelyRetainTiles(this);
1699 }
1700
1701 bool GraphicsLayerCA::platformCALayerShouldTemporarilyRetainTileCohorts(PlatformCALayer*) const
1702 {
1703     return client().shouldTemporarilyRetainTileCohorts(this);
1704 }
1705
1706 bool GraphicsLayerCA::platformCALayerUseGiantTiles() const
1707 {
1708     return client().useGiantTiles();
1709 }
1710
1711 void GraphicsLayerCA::platformCALayerLogFilledVisibleFreshTile(unsigned blankPixelCount)
1712 {
1713     client().logFilledVisibleFreshTile(blankPixelCount);
1714 }
1715
1716 static PlatformCALayer::LayerType layerTypeForCustomBackdropAppearance(GraphicsLayer::CustomAppearance appearance)
1717 {
1718     return appearance == GraphicsLayer::CustomAppearance::LightBackdrop ? PlatformCALayer::LayerTypeLightSystemBackdropLayer : PlatformCALayer::LayerTypeDarkSystemBackdropLayer;
1719 }
1720
1721 static bool isCustomBackdropLayerType(PlatformCALayer::LayerType layerType)
1722 {
1723     return layerType == PlatformCALayer::LayerTypeLightSystemBackdropLayer || layerType == PlatformCALayer::LayerTypeDarkSystemBackdropLayer;
1724 }
1725
1726 void GraphicsLayerCA::commitLayerChangesBeforeSublayers(CommitState& commitState, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool& layerChanged)
1727 {
1728     SetForScope<bool> committingChangesChange(m_isCommittingChanges, true);
1729
1730     ++commitState.treeDepth;
1731     if (m_structuralLayer)
1732         ++commitState.treeDepth;
1733
1734     if (!m_uncommittedChanges) {
1735         // Ensure that we cap layer depth in commitLayerChangesAfterSublayers().
1736         if (commitState.treeDepth > cMaxLayerTreeDepth)
1737             addUncommittedChanges(ChildrenChanged);
1738     }
1739
1740     bool needTiledLayer = requiresTiledLayer(pageScaleFactor);
1741     bool needBackdropLayerType = (customAppearance() == CustomAppearance::LightBackdrop || customAppearance() == CustomAppearance::DarkBackdrop);
1742
1743     PlatformCALayer::LayerType currentLayerType = m_layer->layerType();
1744     PlatformCALayer::LayerType neededLayerType = currentLayerType;
1745
1746     if (needBackdropLayerType)
1747         neededLayerType = layerTypeForCustomBackdropAppearance(customAppearance());
1748     else if (needTiledLayer)
1749         neededLayerType = PlatformCALayer::LayerTypeTiledBackingLayer;
1750     else if (currentLayerType == PlatformCALayer::LayerTypeTiledBackingLayer || isCustomBackdropLayerType(m_layer->layerType()))
1751         neededLayerType = PlatformCALayer::LayerTypeWebLayer;
1752
1753     if (neededLayerType != m_layer->layerType()) {
1754         changeLayerTypeTo(neededLayerType);
1755         layerChanged = true;
1756     }
1757
1758     // Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to
1759     if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged | BackdropFiltersChanged)) {
1760         if (updateStructuralLayer())
1761             layerChanged = true;
1762     }
1763
1764     if (m_uncommittedChanges & GeometryChanged)
1765         updateGeometry(pageScaleFactor, positionRelativeToBase);
1766
1767     if (m_uncommittedChanges & DrawsContentChanged)
1768         updateDrawsContent();
1769
1770     if (m_uncommittedChanges & NameChanged)
1771         updateNames();
1772
1773     if (m_uncommittedChanges & ContentsImageChanged) // Needs to happen before ChildrenChanged
1774         updateContentsImage();
1775         
1776     if (m_uncommittedChanges & ContentsPlatformLayerChanged) // Needs to happen before ChildrenChanged
1777         updateContentsPlatformLayer();
1778
1779     if (m_uncommittedChanges & ContentsColorLayerChanged) // Needs to happen before ChildrenChanged
1780         updateContentsColorLayer();
1781     
1782     if (m_uncommittedChanges & BackgroundColorChanged)
1783         updateBackgroundColor();
1784
1785     if (m_uncommittedChanges & TransformChanged)
1786         updateTransform();
1787
1788     if (m_uncommittedChanges & ChildrenTransformChanged)
1789         updateChildrenTransform();
1790     
1791     if (m_uncommittedChanges & MasksToBoundsChanged)
1792         updateMasksToBounds();
1793     
1794     if (m_uncommittedChanges & ContentsVisibilityChanged)
1795         updateContentsVisibility();
1796
1797     if (m_uncommittedChanges & UserInteractionEnabledChanged)
1798         updateUserInteractionEnabled();
1799
1800     // Note that contentsScale can affect whether the layer can be opaque.
1801     if (m_uncommittedChanges & ContentsOpaqueChanged)
1802         updateContentsOpaque(pageScaleFactor);
1803
1804     if (m_uncommittedChanges & BackfaceVisibilityChanged)
1805         updateBackfaceVisibility();
1806
1807     if (m_uncommittedChanges & OpacityChanged)
1808         updateOpacityOnLayer();
1809
1810     if (m_uncommittedChanges & FiltersChanged)
1811         updateFilters();
1812
1813     // If there are backdrop filters, we need to always check the resource usage
1814     // because something up the tree may have changed its usage.
1815     if (m_uncommittedChanges & BackdropFiltersChanged || needsBackdrop())
1816         updateBackdropFilters(commitState);
1817
1818     if (m_uncommittedChanges & BackdropFiltersRectChanged)
1819         updateBackdropFiltersRect();
1820
1821 #if ENABLE(CSS_COMPOSITING)
1822     if (m_uncommittedChanges & BlendModeChanged)
1823         updateBlendMode();
1824 #endif
1825
1826     if (m_uncommittedChanges & ShapeChanged)
1827         updateShape();
1828
1829     if (m_uncommittedChanges & WindRuleChanged)
1830         updateWindRule();
1831
1832     if (m_uncommittedChanges & AnimationChanged)
1833         updateAnimations();
1834
1835     // Updating the contents scale can cause parts of the layer to be invalidated,
1836     // so make sure to update the contents scale before updating the dirty rects.
1837     if (m_uncommittedChanges & ContentsScaleChanged)
1838         updateContentsScale(pageScaleFactor);
1839
1840     if (m_uncommittedChanges & CoverageRectChanged)
1841         updateCoverage(commitState);
1842
1843     if (m_uncommittedChanges & AcceleratesDrawingChanged) // Needs to happen before TilingAreaChanged.
1844         updateAcceleratesDrawing();
1845
1846     if (m_uncommittedChanges & TilingAreaChanged) // Needs to happen after CoverageRectChanged, ContentsScaleChanged
1847         updateTiles();
1848
1849     if (m_uncommittedChanges & DirtyRectsChanged)
1850         repaintLayerDirtyRects();
1851     
1852     if (m_uncommittedChanges & ContentsRectsChanged) // Needs to happen before ChildrenChanged
1853         updateContentsRects();
1854
1855     if (m_uncommittedChanges & MasksToBoundsRectChanged) // Needs to happen before ChildrenChanged
1856         updateMasksToBoundsRect();
1857
1858     if (m_uncommittedChanges & EventRegionChanged)
1859         updateEventRegion();
1860
1861     if (m_uncommittedChanges & MaskLayerChanged) {
1862         updateMaskLayer();
1863         // If the mask layer becomes tiled it can set this flag again. Clear the flag so that
1864         // commitLayerChangesAfterSublayers doesn't update the mask again in the normal case.
1865         m_uncommittedChanges &= ~MaskLayerChanged;
1866     }
1867
1868     if (m_uncommittedChanges & ContentsNeedsDisplay)
1869         updateContentsNeedsDisplay();
1870
1871     if (m_uncommittedChanges & SupportsSubpixelAntialiasedTextChanged)
1872         updateSupportsSubpixelAntialiasedText();
1873
1874     if (m_uncommittedChanges & DebugIndicatorsChanged)
1875         updateDebugIndicators();
1876
1877     if (m_uncommittedChanges & CustomAppearanceChanged)
1878         updateCustomAppearance();
1879
1880     if (m_uncommittedChanges & ChildrenChanged) {
1881         updateSublayerList();
1882         // Sublayers may set this flag again, so clear it to avoid always updating sublayers in commitLayerChangesAfterSublayers().
1883         m_uncommittedChanges &= ~ChildrenChanged;
1884     }
1885
1886     // Ensure that we cap layer depth in commitLayerChangesAfterSublayers().
1887     if (commitState.treeDepth > cMaxLayerTreeDepth)
1888         addUncommittedChanges(ChildrenChanged);
1889 }
1890
1891 void GraphicsLayerCA::commitLayerChangesAfterSublayers(CommitState& commitState)
1892 {
1893     if (!m_uncommittedChanges)
1894         return;
1895
1896     SetForScope<bool> committingChangesChange(m_isCommittingChanges, true);
1897
1898     if (m_uncommittedChanges & MaskLayerChanged)
1899         updateMaskLayer();
1900
1901     if (m_uncommittedChanges & ChildrenChanged)
1902         updateSublayerList(commitState.treeDepth > cMaxLayerTreeDepth);
1903
1904     if (m_uncommittedChanges & ReplicatedLayerChanged)
1905         updateReplicatedLayers();
1906
1907     m_uncommittedChanges = NoChange;
1908 }
1909
1910 void GraphicsLayerCA::updateNames()
1911 {
1912     switch (structuralLayerPurpose()) {
1913     case StructuralLayerForPreserves3D:
1914         m_structuralLayer->setName("preserve-3d: " + name());
1915         break;
1916     case StructuralLayerForReplicaFlattening:
1917         m_structuralLayer->setName("replica flattening: " + name());
1918         break;
1919     case StructuralLayerForBackdrop:
1920         m_structuralLayer->setName("backdrop hosting: " + name());
1921         break;
1922     case NoStructuralLayer:
1923         break;
1924     }
1925     m_layer->setName(name());
1926 }
1927
1928 void GraphicsLayerCA::updateSublayerList(bool maxLayerDepthReached)
1929 {
1930     if (maxLayerDepthReached) {
1931         m_layer->setSublayers(PlatformCALayerList());
1932         return;
1933     }
1934     
1935     const PlatformCALayerList* customSublayers = m_layer->customSublayers();
1936
1937     PlatformCALayerList structuralLayerChildren;
1938     PlatformCALayerList primaryLayerChildren;
1939
1940     PlatformCALayerList& childListForSublayers = m_structuralLayer ? structuralLayerChildren : primaryLayerChildren;
1941
1942     if (customSublayers)
1943         primaryLayerChildren.appendVector(*customSublayers);
1944
1945     if (m_structuralLayer) {
1946         if (m_backdropLayer)
1947             structuralLayerChildren.append(m_backdropLayer);
1948
1949         if (m_replicaLayer)
1950             structuralLayerChildren.append(downcast<GraphicsLayerCA>(*m_replicaLayer).primaryLayer());
1951     
1952         structuralLayerChildren.append(m_layer);
1953     }
1954
1955     if (m_contentsLayer && m_contentsVisible) {
1956         // FIXME: add the contents layer in the correct order with negative z-order children.
1957         // This does not cause visible rendering issues because currently contents layers are only used
1958         // for replaced elements that don't have children.
1959         primaryLayerChildren.append(m_contentsClippingLayer ? m_contentsClippingLayer : m_contentsLayer);
1960     }
1961     
1962     for (const auto& layer : children()) {
1963         const auto& currentChild = downcast<GraphicsLayerCA>(layer.get());
1964         PlatformCALayer* childLayer = currentChild.layerForSuperlayer();
1965         childListForSublayers.append(childLayer);
1966     }
1967
1968 #ifdef VISIBLE_TILE_WASH
1969     if (m_visibleTileWashLayer)
1970         childListForSublayers.append(m_visibleTileWashLayer);
1971 #endif
1972
1973     if (m_structuralLayer)
1974         m_structuralLayer->setSublayers(structuralLayerChildren);
1975     
1976     m_layer->setSublayers(primaryLayerChildren);
1977 }
1978
1979 void GraphicsLayerCA::updateGeometry(float pageScaleFactor, const FloatPoint& positionRelativeToBase)
1980 {
1981     FloatPoint scaledPosition = m_position;
1982     FloatPoint3D scaledAnchorPoint = m_anchorPoint;
1983     FloatSize scaledSize = m_size;
1984     FloatSize pixelAlignmentOffset;
1985
1986     // FIXME: figure out if we really need to pixel align the graphics layer here.
1987     if (client().needsPixelAligment() && !WTF::isIntegral(pageScaleFactor) && m_drawsContent && !m_masksToBounds)
1988         computePixelAlignment(pageScaleFactor, positionRelativeToBase, scaledPosition, scaledAnchorPoint, pixelAlignmentOffset);
1989
1990     // Update position.
1991     // Position is offset on the layer by the layer anchor point.
1992     FloatPoint adjustedPosition(scaledPosition.x() + scaledAnchorPoint.x() * scaledSize.width(), scaledPosition.y() + scaledAnchorPoint.y() * scaledSize.height());
1993
1994     if (m_structuralLayer) {
1995         FloatPoint layerPosition(m_position.x() + m_anchorPoint.x() * m_size.width(), m_position.y() + m_anchorPoint.y() * m_size.height());
1996         FloatRect layerBounds(m_boundsOrigin, m_size);
1997
1998         m_structuralLayer->setPosition(layerPosition);
1999         m_structuralLayer->setBounds(layerBounds);
2000         m_structuralLayer->setAnchorPoint(m_anchorPoint);
2001
2002         if (m_layerClones) {
2003             for (auto& clone : m_layerClones->structuralLayerClones) {
2004                 PlatformCALayer* cloneLayer = clone.value.get();
2005                 FloatPoint clonePosition = layerPosition;
2006
2007                 if (m_replicaLayer && isReplicatedRootClone(clone.key)) {
2008                     // Maintain the special-case position for the root of a clone subtree,
2009                     // which we set up in replicatedLayerRoot().
2010                     clonePosition = positionForCloneRootLayer();
2011                 }
2012
2013                 cloneLayer->setPosition(clonePosition);
2014                 cloneLayer->setBounds(layerBounds);
2015                 cloneLayer->setAnchorPoint(m_anchorPoint);
2016             }
2017         }
2018
2019         // If we have a structural layer, we just use 0.5, 0.5 for the anchor point of the main layer.
2020         scaledAnchorPoint = FloatPoint(0.5f, 0.5f);
2021         adjustedPosition = FloatPoint(scaledAnchorPoint.x() * scaledSize.width() - pixelAlignmentOffset.width(), scaledAnchorPoint.y() * scaledSize.height() - pixelAlignmentOffset.height());
2022     }
2023
2024     m_pixelAlignmentOffset = pixelAlignmentOffset;
2025
2026     // Push the layer to device pixel boundary (setPosition()), but move the content back to its original position (setBounds())
2027     m_layer->setPosition(adjustedPosition);
2028     FloatRect adjustedBounds = FloatRect(FloatPoint(m_boundsOrigin - pixelAlignmentOffset), m_size);
2029     m_layer->setBounds(adjustedBounds);
2030     m_layer->setAnchorPoint(scaledAnchorPoint);
2031
2032     if (m_layerClones) {
2033         for (auto& clone : m_layerClones->primaryLayerClones) {
2034             PlatformCALayer* cloneLayer = clone.value.get();
2035             FloatPoint clonePosition = adjustedPosition;
2036
2037             if (!m_structuralLayer && m_replicaLayer && isReplicatedRootClone(clone.key)) {
2038                 // Maintain the special-case position for the root of a clone subtree,
2039                 // which we set up in replicatedLayerRoot().
2040                 clonePosition = positionForCloneRootLayer();
2041             }
2042
2043             cloneLayer->setPosition(clonePosition);
2044             cloneLayer->setBounds(adjustedBounds);
2045             cloneLayer->setAnchorPoint(scaledAnchorPoint);
2046         }
2047     }
2048 }
2049
2050 void GraphicsLayerCA::updateTransform()
2051 {
2052     primaryLayer()->setTransform(transform());
2053
2054     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2055         for (auto& clone : *layerCloneMap) {
2056             PlatformCALayer* currLayer = clone.value.get();
2057             if (m_replicaLayer && isReplicatedRootClone(clone.key)) {
2058                 // Maintain the special-case transform for the root of a clone subtree,
2059                 // which we set up in replicatedLayerRoot().
2060                 currLayer->setTransform(TransformationMatrix());
2061             } else
2062                 currLayer->setTransform(transform());
2063         }
2064     }
2065 }
2066
2067 void GraphicsLayerCA::updateChildrenTransform()
2068 {
2069     primaryLayer()->setSublayerTransform(childrenTransform());
2070
2071     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2072         for (auto& layer : layerCloneMap->values())
2073             layer->setSublayerTransform(childrenTransform());
2074     }
2075 }
2076
2077 void GraphicsLayerCA::updateMasksToBounds()
2078 {
2079     m_layer->setMasksToBounds(m_masksToBounds);
2080
2081     if (m_layerClones) {
2082         for (auto& layer : m_layerClones->primaryLayerClones.values())
2083             layer->setMasksToBounds(m_masksToBounds);
2084     }
2085 }
2086
2087 void GraphicsLayerCA::updateContentsVisibility()
2088 {
2089     // Note that m_contentsVisible also affects whether m_contentsLayer is parented.
2090     if (m_contentsVisible) {
2091         if (m_drawsContent)
2092             m_layer->setNeedsDisplay();
2093
2094         if (m_backdropLayer)
2095             m_backdropLayer->setHidden(false);
2096     } else {
2097         m_layer->setContents(nullptr);
2098
2099         if (m_layerClones) {
2100             for (auto& layer : m_layerClones->primaryLayerClones.values())
2101                 layer->setContents(nullptr);
2102         }
2103
2104         if (m_backdropLayer)
2105             m_backdropLayer->setHidden(true);
2106     }
2107
2108     m_layer->setContentsHidden(!m_contentsVisible);
2109 }
2110
2111 void GraphicsLayerCA::updateUserInteractionEnabled()
2112 {
2113     m_layer->setUserInteractionEnabled(m_userInteractionEnabled);
2114 }
2115
2116 void GraphicsLayerCA::updateContentsOpaque(float pageScaleFactor)
2117 {
2118     bool contentsOpaque = m_contentsOpaque;
2119     if (contentsOpaque) {
2120         float contentsScale = pageScaleFactor * deviceScaleFactor();
2121         if (!WTF::isIntegral(contentsScale) && !client().paintsOpaquelyAtNonIntegralScales(this))
2122             contentsOpaque = false;
2123     }
2124     
2125     m_layer->setOpaque(contentsOpaque);
2126
2127     if (m_layerClones) {
2128         for (auto& layer : m_layerClones->primaryLayerClones.values())
2129             layer->setOpaque(contentsOpaque);
2130     }
2131 }
2132
2133 void GraphicsLayerCA::updateBackfaceVisibility()
2134 {
2135     if (m_structuralLayer && structuralLayerPurpose() == StructuralLayerForReplicaFlattening) {
2136         m_structuralLayer->setDoubleSided(m_backfaceVisibility);
2137
2138         if (m_layerClones) {
2139             for (auto& layer : m_layerClones->structuralLayerClones.values())
2140                 layer->setDoubleSided(m_backfaceVisibility);
2141         }
2142     }
2143
2144     m_layer->setDoubleSided(m_backfaceVisibility);
2145
2146     if (m_layerClones) {
2147         for (auto& layer : m_layerClones->primaryLayerClones.values())
2148             layer->setDoubleSided(m_backfaceVisibility);
2149     }
2150 }
2151
2152 void GraphicsLayerCA::updateFilters()
2153 {
2154     m_layer->setFilters(m_filters);
2155
2156     if (m_layerClones) {
2157         for (auto& clone : m_layerClones->primaryLayerClones) {
2158             if (m_replicaLayer && isReplicatedRootClone(clone.key))
2159                 continue;
2160
2161             clone.value->setFilters(m_filters);
2162         }
2163     }
2164 }
2165
2166 void GraphicsLayerCA::updateBackdropFilters(CommitState& commitState)
2167 {
2168     using CheckedUnsigned = Checked<unsigned, RecordOverflow>;
2169
2170     bool canHaveBackdropFilters = needsBackdrop();
2171
2172     if (canHaveBackdropFilters) {
2173         canHaveBackdropFilters = false;
2174         IntRect backdropFilterRect = enclosingIntRect(m_backdropFiltersRect.rect());
2175         if (backdropFilterRect.width() > 0 && backdropFilterRect.height() > 0) {
2176             CheckedUnsigned backdropFilterArea = CheckedUnsigned(backdropFilterRect.width()) * CheckedUnsigned(backdropFilterRect.height());
2177             if (!backdropFilterArea.hasOverflowed()) {
2178                 CheckedUnsigned newTotalBackdropFilterArea = CheckedUnsigned(commitState.totalBackdropFilterArea) + backdropFilterArea;
2179                 if (!newTotalBackdropFilterArea.hasOverflowed() && newTotalBackdropFilterArea.unsafeGet() <= cMaxTotalBackdropFilterArea) {
2180                     commitState.totalBackdropFilterArea = newTotalBackdropFilterArea.unsafeGet();
2181                     canHaveBackdropFilters = true;
2182                 }
2183             }
2184         }
2185     }
2186
2187     if (!canHaveBackdropFilters) {
2188         if (m_backdropLayer) {
2189             m_backdropLayer->removeFromSuperlayer();
2190             m_backdropLayer->setOwner(nullptr);
2191             m_backdropLayer = nullptr;
2192         }
2193         return;
2194     }
2195
2196     // If nothing actually changed, no need to touch the layer properties.
2197     if (!(m_uncommittedChanges & BackdropFiltersChanged))
2198         return;
2199
2200     bool madeLayer = !m_backdropLayer;
2201     if (!m_backdropLayer) {
2202         m_backdropLayer = createPlatformCALayer(PlatformCALayer::LayerTypeBackdropLayer, this);
2203         m_backdropLayer->setAnchorPoint(FloatPoint3D());
2204         m_backdropLayer->setMasksToBounds(true);
2205         m_backdropLayer->setName("backdrop");
2206     }
2207
2208     m_backdropLayer->setHidden(!m_contentsVisible);
2209     m_backdropLayer->setFilters(m_backdropFilters);
2210
2211     if (m_layerClones) {
2212         for (auto& clone : m_layerClones->backdropLayerClones) {
2213             PlatformCALayer* cloneLayer = clone.value.get();
2214             cloneLayer->setHidden(!m_contentsVisible);
2215             cloneLayer->setFilters(m_backdropFilters);
2216         }
2217     }
2218
2219     if (madeLayer) {
2220         updateBackdropFiltersRect();
2221         noteSublayersChanged(DontScheduleFlush);
2222     }
2223 }
2224
2225 void GraphicsLayerCA::updateBackdropFiltersRect()
2226 {
2227     if (!m_backdropLayer)
2228         return;
2229
2230     FloatRect contentBounds(0, 0, m_backdropFiltersRect.rect().width(), m_backdropFiltersRect.rect().height());
2231     m_backdropLayer->setBounds(contentBounds);
2232     m_backdropLayer->setPosition(m_backdropFiltersRect.rect().location());
2233
2234     updateClippingStrategy(*m_backdropLayer, m_backdropClippingLayer, m_backdropFiltersRect);
2235
2236     if (m_layerClones) {
2237         for (auto& clone : m_layerClones->backdropLayerClones) {
2238             PlatformCALayer* backdropCloneLayer = clone.value.get();
2239             backdropCloneLayer->setBounds(contentBounds);
2240             backdropCloneLayer->setPosition(m_backdropFiltersRect.rect().location());
2241
2242             CloneID cloneID = clone.key;
2243             RefPtr<PlatformCALayer> backdropClippingLayerClone = m_layerClones->backdropClippingLayerClones.get(cloneID);
2244
2245             bool hadBackdropClippingLayer = backdropClippingLayerClone;
2246             updateClippingStrategy(*backdropCloneLayer, backdropClippingLayerClone, m_backdropFiltersRect);
2247
2248             if (!backdropClippingLayerClone)
2249                 m_layerClones->backdropClippingLayerClones.remove(cloneID);
2250             else if (backdropClippingLayerClone && !hadBackdropClippingLayer)
2251                 m_layerClones->backdropClippingLayerClones.add(cloneID, backdropClippingLayerClone);
2252         }
2253     }
2254 }
2255
2256 #if ENABLE(CSS_COMPOSITING)
2257 void GraphicsLayerCA::updateBlendMode()
2258 {
2259     primaryLayer()->setBlendMode(m_blendMode);
2260
2261     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2262         for (auto& clone : *layerCloneMap) {
2263             if (m_replicaLayer && isReplicatedRootClone(clone.key))
2264                 continue;
2265             clone.value->setBlendMode(m_blendMode);
2266         }
2267     }
2268 }
2269 #endif
2270
2271 void GraphicsLayerCA::updateShape()
2272 {
2273     m_layer->setShapePath(m_shapeLayerPath);
2274
2275     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2276         for (auto& layer : layerCloneMap->values())
2277             layer->setShapePath(m_shapeLayerPath);
2278     }
2279 }
2280
2281 void GraphicsLayerCA::updateWindRule()
2282 {
2283     m_layer->setShapeWindRule(m_shapeLayerWindRule);
2284 }
2285
2286 bool GraphicsLayerCA::updateStructuralLayer()
2287 {
2288     return ensureStructuralLayer(structuralLayerPurpose());
2289 }
2290
2291 bool GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose)
2292 {
2293     const LayerChangeFlags structuralLayerChangeFlags = NameChanged
2294         | GeometryChanged
2295         | TransformChanged
2296         | ChildrenTransformChanged
2297         | ChildrenChanged
2298         | BackfaceVisibilityChanged
2299         | FiltersChanged
2300         | BackdropFiltersChanged
2301         | MaskLayerChanged
2302         | OpacityChanged;
2303
2304     bool structuralLayerChanged = false;
2305
2306     if (purpose == NoStructuralLayer) {
2307         if (m_structuralLayer) {
2308             // Replace the transformLayer in the parent with this layer.
2309             m_layer->removeFromSuperlayer();
2310  
2311             // If m_layer doesn't have a parent, it means it's the root layer and
2312             // is likely hosted by something that is not expecting to be changed
2313             ASSERT(m_structuralLayer->superlayer());
2314             m_structuralLayer->superlayer()->replaceSublayer(*m_structuralLayer, *m_layer);
2315
2316             moveAnimations(m_structuralLayer.get(), m_layer.get());
2317
2318             // Release the structural layer.
2319             m_structuralLayer = nullptr;
2320             structuralLayerChanged = true;
2321
2322             addUncommittedChanges(structuralLayerChangeFlags);
2323         }
2324         return structuralLayerChanged;
2325     }
2326
2327     if (purpose == StructuralLayerForPreserves3D) {
2328         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeTransformLayer)
2329             m_structuralLayer = nullptr;
2330         
2331         if (!m_structuralLayer) {
2332             m_structuralLayer = createPlatformCALayer(PlatformCALayer::LayerTypeTransformLayer, this);
2333             structuralLayerChanged = true;
2334         }
2335     } else {
2336         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeLayer)
2337             m_structuralLayer = nullptr;
2338
2339         if (!m_structuralLayer) {
2340             m_structuralLayer = createPlatformCALayer(PlatformCALayer::LayerTypeLayer, this);
2341             structuralLayerChanged = true;
2342         }
2343     }
2344     
2345     if (!structuralLayerChanged)
2346         return false;
2347     
2348     addUncommittedChanges(structuralLayerChangeFlags);
2349
2350     // We've changed the layer that our parent added to its sublayer list, so tell it to update
2351     // sublayers again in its commitLayerChangesAfterSublayers().
2352     downcast<GraphicsLayerCA>(*parent()).noteSublayersChanged(DontScheduleFlush);
2353
2354     // Set properties of m_layer to their default values, since these are expressed on on the structural layer.
2355     FloatPoint point(m_size.width() / 2.0f, m_size.height() / 2.0f);
2356     FloatPoint3D anchorPoint(0.5f, 0.5f, 0);
2357     m_layer->setPosition(point);
2358     m_layer->setAnchorPoint(anchorPoint);
2359     m_layer->setTransform(TransformationMatrix());
2360     m_layer->setOpacity(1);
2361     if (m_layerClones) {
2362         for (auto& layer : m_layerClones->primaryLayerClones.values()) {
2363             layer->setPosition(point);
2364             layer->setAnchorPoint(anchorPoint);
2365             layer->setTransform(TransformationMatrix());
2366             layer->setOpacity(1);
2367         }
2368     }
2369
2370     moveAnimations(m_layer.get(), m_structuralLayer.get());
2371     return true;
2372 }
2373
2374 GraphicsLayerCA::StructuralLayerPurpose GraphicsLayerCA::structuralLayerPurpose() const
2375 {
2376     if (preserves3D())
2377         return StructuralLayerForPreserves3D;
2378     
2379     if (isReplicated())
2380         return StructuralLayerForReplicaFlattening;
2381
2382     if (needsBackdrop())
2383         return StructuralLayerForBackdrop;
2384
2385     return NoStructuralLayer;
2386 }
2387
2388 void GraphicsLayerCA::updateDrawsContent()
2389 {
2390     if (m_drawsContent) {
2391         m_layer->setNeedsDisplay();
2392         m_hasEverPainted = false;
2393     } else {
2394         m_layer->setContents(nullptr);
2395         if (m_layerClones) {
2396             for (auto& layer : m_layerClones->primaryLayerClones.values())
2397                 layer->setContents(nullptr);
2398         }
2399     }
2400 }
2401
2402 void GraphicsLayerCA::updateCoverage(const CommitState& commitState)
2403 {
2404     // FIXME: Need to set coverage on clone layers too.
2405     if (TiledBacking* backing = tiledBacking()) {
2406         backing->setVisibleRect(m_visibleRect);
2407         backing->setCoverageRect(m_coverageRect);
2408     }
2409
2410     if (canDetachBackingStore()) {
2411         bool requiresBacking = m_intersectsCoverageRect
2412             || commitState.ancestorWithTransformAnimationIntersectsCoverageRect // FIXME: Compute backing exactly for descendants of animating layers.
2413             || (isRunningTransformAnimation() && !animationExtent()); // Create backing if we don't know the animation extent.
2414
2415 #if !LOG_DISABLED
2416         if (requiresBacking) {
2417             auto reasonForBacking = [&]() -> const char* {
2418                 if (m_intersectsCoverageRect)
2419                     return "intersectsCoverageRect";
2420                 
2421                 if (commitState.ancestorWithTransformAnimationIntersectsCoverageRect)
2422                     return "ancestor with transform";
2423                 
2424                 return "has transform animation with unknown extent";
2425             };
2426             LOG_WITH_STREAM(Compositing, stream << "GraphicsLayerCA " << this << " id " << primaryLayerID() << " setBackingStoreAttached: " << requiresBacking << " (" << reasonForBacking() << ")");
2427         } else
2428             LOG_WITH_STREAM(Compositing, stream << "GraphicsLayerCA " << this << " id " << primaryLayerID() << " setBackingStoreAttached: " << requiresBacking);
2429 #endif
2430
2431         m_layer->setBackingStoreAttached(requiresBacking);
2432         if (m_layerClones) {
2433             for (auto& layer : m_layerClones->primaryLayerClones.values())
2434                 layer->setBackingStoreAttached(requiresBacking);
2435         }
2436     }
2437
2438     m_sizeAtLastCoverageRectUpdate = m_size;
2439 }
2440
2441 void GraphicsLayerCA::updateAcceleratesDrawing()
2442 {
2443     m_layer->setAcceleratesDrawing(m_acceleratesDrawing);
2444 }
2445
2446 void GraphicsLayerCA::updateSupportsSubpixelAntialiasedText()
2447 {
2448     m_layer->setSupportsSubpixelAntialiasedText(m_supportsSubpixelAntialiasedText);
2449 }
2450
2451 static void setLayerDebugBorder(PlatformCALayer& layer, Color borderColor, float borderWidth)
2452 {
2453     layer.setBorderColor(borderColor);
2454     layer.setBorderWidth(borderColor.isValid() ? borderWidth : 0);
2455 }
2456
2457 static const float contentsLayerBorderWidth = 4;
2458 static Color contentsLayerDebugBorderColor(bool showingBorders)
2459 {
2460     return showingBorders ? Color(0, 0, 128, 180) : Color();
2461 }
2462
2463 static const float cloneLayerBorderWidth = 2;
2464 static Color cloneLayerDebugBorderColor(bool showingBorders)
2465 {
2466     return showingBorders ? Color(255, 122, 251) : Color();
2467 }
2468
2469 void GraphicsLayerCA::updateDebugIndicators()
2470 {
2471     Color borderColor;
2472     float width = 0;
2473
2474     bool showDebugBorders = isShowingDebugBorder();
2475     if (showDebugBorders)
2476         getDebugBorderInfo(borderColor, width);
2477
2478     // Paint repaint counter.
2479     m_layer->setNeedsDisplay();
2480
2481     setLayerDebugBorder(*m_layer, borderColor, width);
2482     if (m_contentsLayer)
2483         setLayerDebugBorder(*m_contentsLayer, contentsLayerDebugBorderColor(showDebugBorders), contentsLayerBorderWidth);
2484
2485     if (m_layerClones) {
2486         for (auto& layer : m_layerClones->primaryLayerClones.values())
2487             setLayerDebugBorder(*layer, borderColor, width);
2488
2489         Color cloneLayerBorderColor = cloneLayerDebugBorderColor(showDebugBorders);
2490         for (auto& layer : m_layerClones->structuralLayerClones.values())
2491             setLayerDebugBorder(*layer, cloneLayerBorderColor, cloneLayerBorderWidth);
2492
2493         Color contentsLayerBorderColor = contentsLayerDebugBorderColor(showDebugBorders);
2494         for (auto& layer : m_layerClones->contentsLayerClones.values())
2495             setLayerDebugBorder(*layer, contentsLayerBorderColor, contentsLayerBorderWidth);
2496     }
2497 }
2498
2499 FloatRect GraphicsLayerCA::adjustTiledLayerVisibleRect(TiledBacking* tiledBacking, const FloatRect& oldVisibleRect, const FloatRect& newVisibleRect, const FloatSize& oldSize, const FloatSize& newSize)
2500 {
2501     // If the old visible rect is empty, we have no information about how the visible area is changing
2502     // (maybe the layer was just created), so don't attempt to expand. Also don't attempt to expand
2503     // if the size changed or the rects don't overlap.
2504     if (oldVisibleRect.isEmpty() || newSize != oldSize || !newVisibleRect.intersects(oldVisibleRect))
2505         return newVisibleRect;
2506
2507     if (MemoryPressureHandler::singleton().isUnderMemoryPressure())
2508         return newVisibleRect;
2509
2510     const float paddingMultiplier = 2;
2511
2512     float leftEdgeDelta = paddingMultiplier * (newVisibleRect.x() - oldVisibleRect.x());
2513     float rightEdgeDelta = paddingMultiplier * (newVisibleRect.maxX() - oldVisibleRect.maxX());
2514
2515     float topEdgeDelta = paddingMultiplier * (newVisibleRect.y() - oldVisibleRect.y());
2516     float bottomEdgeDelta = paddingMultiplier * (newVisibleRect.maxY() - oldVisibleRect.maxY());
2517     
2518     FloatRect existingTileBackingRect = tiledBacking->visibleRect();
2519     FloatRect expandedRect = newVisibleRect;
2520
2521     // More exposed on left side.
2522     if (leftEdgeDelta < 0) {
2523         float newLeft = expandedRect.x() + leftEdgeDelta;
2524         // Pad to the left, but don't reduce padding that's already in the backing store (since we're still exposing to the left).
2525         if (newLeft < existingTileBackingRect.x())
2526             expandedRect.shiftXEdgeTo(newLeft);
2527         else
2528             expandedRect.shiftXEdgeTo(existingTileBackingRect.x());
2529     }
2530
2531     // More exposed on right.
2532     if (rightEdgeDelta > 0) {
2533         float newRight = expandedRect.maxX() + rightEdgeDelta;
2534         // Pad to the right, but don't reduce padding that's already in the backing store (since we're still exposing to the right).
2535         if (newRight > existingTileBackingRect.maxX())
2536             expandedRect.setWidth(newRight - expandedRect.x());
2537         else
2538             expandedRect.setWidth(existingTileBackingRect.maxX() - expandedRect.x());
2539     }
2540
2541     // More exposed at top.
2542     if (topEdgeDelta < 0) {
2543         float newTop = expandedRect.y() + topEdgeDelta;
2544         if (newTop < existingTileBackingRect.y())
2545             expandedRect.shiftYEdgeTo(newTop);
2546         else
2547             expandedRect.shiftYEdgeTo(existingTileBackingRect.y());
2548     }
2549
2550     // More exposed on bottom.
2551     if (bottomEdgeDelta > 0) {
2552         float newBottom = expandedRect.maxY() + bottomEdgeDelta;
2553         if (newBottom > existingTileBackingRect.maxY())
2554             expandedRect.setHeight(newBottom - expandedRect.y());
2555         else
2556             expandedRect.setHeight(existingTileBackingRect.maxY() - expandedRect.y());
2557     }
2558     
2559     expandedRect.intersect(tiledBacking->boundsWithoutMargin());
2560     return expandedRect;
2561 }
2562
2563 void GraphicsLayerCA::updateTiles()
2564 {
2565     if (!m_layer->usesTiledBackingLayer())
2566         return;
2567
2568     tiledBacking()->revalidateTiles();
2569 }
2570
2571 void GraphicsLayerCA::updateBackgroundColor()
2572 {
2573     m_layer->setBackgroundColor(m_backgroundColor);
2574 }
2575
2576 void GraphicsLayerCA::updateContentsImage()
2577 {
2578     if (m_pendingContentsImage) {
2579         if (!m_contentsLayer.get()) {
2580             m_contentsLayer = createPlatformCALayer(PlatformCALayer::LayerTypeLayer, this);
2581 #if ENABLE(TREE_DEBUGGING)
2582             m_contentsLayer->setName(makeString("contents image ", m_contentsLayer->layerID()));
2583 #else
2584             m_contentsLayer->setName("contents image");
2585 #endif
2586             setupContentsLayer(m_contentsLayer.get());
2587             // m_contentsLayer will be parented by updateSublayerList
2588         }
2589
2590         // FIXME: maybe only do trilinear if the image is being scaled down,
2591         // but then what if the layer size changes?
2592         m_contentsLayer->setMinificationFilter(PlatformCALayer::Trilinear);
2593         m_contentsLayer->setContents(m_pendingContentsImage.get());
2594         m_pendingContentsImage = nullptr;
2595
2596         if (m_layerClones) {
2597             for (auto& layer : m_layerClones->contentsLayerClones.values())
2598                 layer->setContents(m_contentsLayer->contents());
2599         }
2600         
2601         updateContentsRects();
2602     } else {
2603         // No image.
2604         // m_contentsLayer will be removed via updateSublayerList.
2605         m_contentsLayer = nullptr;
2606     }
2607 }
2608
2609 void GraphicsLayerCA::updateContentsPlatformLayer()
2610 {
2611     if (!m_contentsLayer)
2612         return;
2613
2614     // Platform layer was set as m_contentsLayer, and will get parented in updateSublayerList().
2615     setupContentsLayer(m_contentsLayer.get());
2616
2617     if (m_contentsLayerPurpose == ContentsLayerPurpose::Canvas)
2618         m_contentsLayer->setNeedsDisplay();
2619
2620     updateContentsRects();
2621 }
2622
2623 void GraphicsLayerCA::updateContentsColorLayer()
2624 {
2625     // Color layer was set as m_contentsLayer, and will get parented in updateSublayerList().
2626     if (!m_contentsLayer || m_contentsLayerPurpose != ContentsLayerPurpose::BackgroundColor)
2627         return;
2628
2629     setupContentsLayer(m_contentsLayer.get());
2630     updateContentsRects();
2631     ASSERT(m_contentsSolidColor.isValid());
2632     m_contentsLayer->setBackgroundColor(m_contentsSolidColor);
2633
2634     if (m_layerClones) {
2635         for (auto& layer : m_layerClones->contentsLayerClones.values())
2636             layer->setBackgroundColor(m_contentsSolidColor);
2637     }
2638 }
2639
2640 // The clipping strategy depends on whether the rounded rect has equal corner radii.
2641 void GraphicsLayerCA::updateClippingStrategy(PlatformCALayer& clippingLayer, RefPtr<PlatformCALayer>& shapeMaskLayer, const FloatRoundedRect& roundedRect)
2642 {
2643     if (roundedRect.radii().isUniformCornerRadius()) {
2644         clippingLayer.setMask(nullptr);
2645         if (shapeMaskLayer) {
2646             shapeMaskLayer->setOwner(nullptr);
2647             shapeMaskLayer = nullptr;
2648         }
2649
2650         clippingLayer.setMasksToBounds(true);
2651         clippingLayer.setCornerRadius(roundedRect.radii().topLeft().width());
2652         return;
2653     }
2654
2655     if (!shapeMaskLayer) {
2656         shapeMaskLayer = createPlatformCALayer(PlatformCALayer::LayerTypeShapeLayer, this);
2657         shapeMaskLayer->setAnchorPoint(FloatPoint3D());
2658         shapeMaskLayer->setName("shape mask");
2659     }
2660     
2661     shapeMaskLayer->setPosition(FloatPoint());
2662     shapeMaskLayer->setBounds(clippingLayer.bounds());
2663
2664     clippingLayer.setCornerRadius(0);
2665     clippingLayer.setMask(shapeMaskLayer.get());
2666     
2667     FloatRoundedRect offsetRoundedRect(clippingLayer.bounds(), roundedRect.radii());
2668     shapeMaskLayer->setShapeRoundedRect(offsetRoundedRect);
2669 }
2670
2671 void GraphicsLayerCA::updateContentsRects()
2672 {
2673     if (!m_contentsLayer)
2674         return;
2675
2676     FloatPoint contentOrigin;
2677     const FloatRect contentBounds(0, 0, m_contentsRect.width(), m_contentsRect.height());
2678
2679     FloatPoint clippingOrigin(m_contentsClippingRect.rect().location());
2680     FloatRect clippingBounds(FloatPoint(), m_contentsClippingRect.rect().size());
2681     
2682     bool gainedOrLostClippingLayer = false;
2683     if (m_contentsClippingRect.isRounded() || !m_contentsClippingRect.rect().contains(m_contentsRect)) {
2684         if (!m_contentsClippingLayer) {
2685             m_contentsClippingLayer = createPlatformCALayer(PlatformCALayer::LayerTypeLayer, this);
2686             m_contentsClippingLayer->setAnchorPoint(FloatPoint());
2687 #if ENABLE(TREE_DEBUGGING)
2688             m_contentsClippingLayer->setName(makeString("contents clipping ", m_contentsClippingLayer->layerID()));
2689 #else
2690             m_contentsClippingLayer->setName("contents clipping");
2691 #endif
2692             gainedOrLostClippingLayer = true;
2693         }
2694
2695         m_contentsClippingLayer->setPosition(clippingOrigin);
2696         m_contentsClippingLayer->setBounds(clippingBounds);
2697
2698         updateClippingStrategy(*m_contentsClippingLayer, m_contentsShapeMaskLayer, m_contentsClippingRect);
2699
2700         if (gainedOrLostClippingLayer) {
2701             m_contentsLayer->removeFromSuperlayer();
2702             m_contentsClippingLayer->appendSublayer(*m_contentsLayer);
2703         }
2704     
2705         contentOrigin = FloatPoint(m_contentsRect.location() - m_contentsClippingRect.rect().location());
2706     } else {
2707         if (m_contentsClippingLayer) {
2708             m_contentsLayer->removeFromSuperlayer();
2709
2710             m_contentsClippingLayer->removeFromSuperlayer();
2711             m_contentsClippingLayer->setOwner(nullptr);
2712             m_contentsClippingLayer->setMask(nullptr);
2713             m_contentsClippingLayer = nullptr;
2714             gainedOrLostClippingLayer = true;
2715         }
2716
2717         if (m_contentsShapeMaskLayer) {
2718             m_contentsShapeMaskLayer->setOwner(nullptr);
2719             m_contentsShapeMaskLayer = nullptr;
2720         }
2721
2722         contentOrigin = m_contentsRect.location();
2723     }
2724     
2725     if (gainedOrLostClippingLayer)
2726         noteSublayersChanged(DontScheduleFlush);
2727
2728     m_contentsLayer->setPosition(contentOrigin);
2729     m_contentsLayer->setBounds(contentBounds);
2730
2731     if (m_layerClones) {
2732         for (auto& layer : m_layerClones->contentsLayerClones.values()) {
2733             layer->setPosition(contentOrigin);
2734             layer->setBounds(contentBounds);
2735         }
2736
2737         for (auto& clone : m_layerClones->contentsClippingLayerClones) {
2738             CloneID cloneID = clone.key;
2739             RefPtr<PlatformCALayer> shapeMaskLayerClone = m_layerClones->contentsShapeMaskLayerClones.get(cloneID);
2740
2741             bool hadShapeMask = shapeMaskLayerClone;
2742             updateClippingStrategy(*clone.value, shapeMaskLayerClone, m_contentsClippingRect);
2743
2744             if (!shapeMaskLayerClone)
2745                 m_layerClones->contentsShapeMaskLayerClones.remove(cloneID);
2746             else if (shapeMaskLayerClone && !hadShapeMask)
2747                 m_layerClones->contentsShapeMaskLayerClones.add(cloneID, shapeMaskLayerClone);
2748         }
2749     }
2750 }
2751
2752 void GraphicsLayerCA::updateMasksToBoundsRect()
2753 {
2754     updateClippingStrategy(*m_layer, m_shapeMaskLayer, m_masksToBoundsRect);
2755
2756     if (m_layerClones) {
2757         for (auto& clone : m_layerClones->primaryLayerClones) {
2758             CloneID cloneID = clone.key;
2759             RefPtr<PlatformCALayer> shapeMaskLayerClone = m_layerClones->shapeMaskLayerClones.get(cloneID);
2760
2761             bool hadShapeMask = shapeMaskLayerClone;
2762             updateClippingStrategy(*clone.value, shapeMaskLayerClone, m_masksToBoundsRect);
2763
2764             if (!shapeMaskLayerClone)
2765                 m_layerClones->shapeMaskLayerClones.remove(cloneID);
2766             else if (!hadShapeMask && shapeMaskLayerClone)
2767                 m_layerClones->shapeMaskLayerClones.add(cloneID, shapeMaskLayerClone);
2768         }
2769     }
2770 }
2771
2772 void GraphicsLayerCA::updateEventRegion()
2773 {
2774     m_layer->setEventRegion(eventRegion());
2775 }
2776
2777 void GraphicsLayerCA::updateMaskLayer()
2778 {
2779     PlatformCALayer* maskCALayer = m_maskLayer ? downcast<GraphicsLayerCA>(*m_maskLayer).primaryLayer() : nullptr;
2780     
2781     LayerMap* layerCloneMap;
2782     if (m_structuralLayer && structuralLayerPurpose() == StructuralLayerForBackdrop) {
2783         m_structuralLayer->setMask(maskCALayer);
2784         layerCloneMap = m_layerClones ? &m_layerClones->structuralLayerClones : nullptr;
2785     } else {
2786         m_layer->setMask(maskCALayer);
2787         layerCloneMap = m_layerClones ? &m_layerClones->primaryLayerClones : nullptr;
2788     }
2789
2790     LayerMap* maskLayerCloneMap = m_maskLayer ? downcast<GraphicsLayerCA>(*m_maskLayer).primaryLayerClones() : nullptr;
2791     if (layerCloneMap) {
2792         for (auto& clone : *layerCloneMap) {
2793             PlatformCALayer* maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(clone.key) : nullptr;
2794             clone.value->setMask(maskClone);
2795         }
2796     }
2797 }
2798
2799 void GraphicsLayerCA::updateReplicatedLayers()
2800 {
2801     // Clone the descendants of the replicated layer, and parent under us.
2802     ReplicaState replicaState(ReplicaState::ReplicaBranch);
2803
2804     RefPtr<PlatformCALayer>replicaRoot = replicatedLayerRoot(replicaState);
2805     if (!replicaRoot)
2806         return;
2807
2808     if (m_structuralLayer)
2809         m_structuralLayer->insertSublayer(*replicaRoot, 0);
2810     else
2811         m_layer->insertSublayer(*replicaRoot, 0);
2812 }
2813
2814 // For now, this assumes that layers only ever have one replica, so replicaIndices contains only 0 and 1.
2815 GraphicsLayerCA::CloneID GraphicsLayerCA::ReplicaState::cloneID() const
2816 {
2817     size_t depth = m_replicaBranches.size();
2818
2819     const size_t bitsPerUChar = sizeof(UChar) * 8;
2820     size_t vectorSize = (depth + bitsPerUChar - 1) / bitsPerUChar;
2821     
2822     Vector<UChar> result(vectorSize);
2823     result.fill(0);
2824
2825     // Create a string from the bit sequence which we can use to identify the clone.
2826     // Note that the string may contain embedded nulls, but that's OK.
2827     for (size_t i = 0; i < depth; ++i) {
2828         UChar& currChar = result[i / bitsPerUChar];
2829         currChar = (currChar << 1) | m_replicaBranches[i];
2830     }
2831     
2832     return String::adopt(WTFMove(result));
2833 }
2834
2835 RefPtr<PlatformCALayer> GraphicsLayerCA::replicatedLayerRoot(ReplicaState& replicaState)
2836 {
2837     // Limit replica nesting, to avoid 2^N explosion of replica layers.
2838     if (!m_replicatedLayer || replicaState.replicaDepth() == ReplicaState::maxReplicaDepth)
2839         return nullptr;
2840
2841     GraphicsLayerCA& replicatedLayer = downcast<GraphicsLayerCA>(*m_replicatedLayer);
2842     
2843     RefPtr<PlatformCALayer> clonedLayerRoot = replicatedLayer.fetchCloneLayers(this, replicaState, RootCloneLevel);
2844     FloatPoint cloneRootPosition = replicatedLayer.positionForCloneRootLayer();
2845
2846     // Replica root has no offset or transform
2847     clonedLayerRoot->setPosition(cloneRootPosition);
2848     clonedLayerRoot->setTransform(TransformationMatrix());
2849
2850     return clonedLayerRoot;
2851 }
2852
2853 void GraphicsLayerCA::updateAnimations()
2854 {
2855     if (!hasAnimations())
2856         return;
2857
2858     size_t numAnimations;
2859     if ((numAnimations = m_animations->uncomittedAnimations.size())) {
2860         for (size_t i = 0; i < numAnimations; ++i) {
2861             const LayerPropertyAnimation& pendingAnimation = m_animations->uncomittedAnimations[i];
2862             setAnimationOnLayer(*pendingAnimation.m_animation, pendingAnimation.m_property, pendingAnimation.m_name, pendingAnimation.m_index, pendingAnimation.m_subIndex, pendingAnimation.m_timeOffset);
2863
2864             AnimationsMap::iterator it = m_animations->runningAnimations.find(pendingAnimation.m_name);
2865             if (it == m_animations->runningAnimations.end()) {
2866                 Vector<LayerPropertyAnimation> animations;
2867                 animations.append(pendingAnimation);
2868                 m_animations->runningAnimations.add(pendingAnimation.m_name, animations);
2869             } else {
2870                 Vector<LayerPropertyAnimation>& animations = it->value;
2871                 animations.append(pendingAnimation);
2872             }
2873         }
2874         m_animations->uncomittedAnimations.clear();
2875     }
2876
2877     if (m_animations->animationsToProcess.size()) {
2878         for (const auto& it : m_animations->animationsToProcess) {
2879             const String& currentAnimationName = it.key;
2880             auto animationIterator = m_animations->runningAnimations.find(currentAnimationName);
2881             if (animationIterator == m_animations->runningAnimations.end())
2882                 continue;
2883
2884             for (const auto& processingInfo : it.value) {
2885                 const Vector<LayerPropertyAnimation>& animations = animationIterator->value;
2886                 for (const auto& currentAnimation : animations) {
2887                     switch (processingInfo.action) {
2888                     case Remove:
2889                         removeCAAnimationFromLayer(currentAnimation.m_property, currentAnimationName, currentAnimation.m_index, currentAnimation.m_subIndex);
2890                         break;
2891                     case Pause:
2892                         pauseCAAnimationOnLayer(currentAnimation.m_property, currentAnimationName, currentAnimation.m_index, currentAnimation.m_subIndex, processingInfo.timeOffset);
2893                         break;
2894                     case Seek:
2895                         seekCAAnimationOnLayer(currentAnimation.m_property, currentAnimationName, currentAnimation.m_index, currentAnimation.m_subIndex, processingInfo.timeOffset);
2896                         break;
2897                     }
2898                 }
2899
2900                 if (processingInfo.action == Remove)
2901                     m_animations->runningAnimations.remove(currentAnimationName);
2902             }
2903         }
2904
2905         m_animations->animationsToProcess.clear();
2906     }
2907 }
2908
2909 bool GraphicsLayerCA::isRunningTransformAnimation() const
2910 {
2911     if (!hasAnimations())
2912         return false;
2913
2914     for (const auto& it : m_animations->runningAnimations) {
2915         const auto& propertyAnimations = it.value;
2916         size_t numAnimations = propertyAnimations.size();
2917         for (size_t i = 0; i < numAnimations; ++i) {
2918             const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
2919             if (currAnimation.m_property == AnimatedPropertyTransform)
2920                 return true;
2921         }
2922     }
2923     return false;
2924 }
2925
2926 void GraphicsLayerCA::ensureLayerAnimations()
2927 {
2928     if (!m_animations)
2929         m_animations = std::make_unique<LayerAnimations>();
2930 }
2931
2932 void GraphicsLayerCA::setAnimationOnLayer(PlatformCAAnimation& caAnim, AnimatedPropertyID property, const String& animationName, int index, int subIndex, Seconds timeOffset)
2933 {
2934     PlatformCALayer* layer = animatedLayer(property);
2935
2936     if (timeOffset)
2937         caAnim.setBeginTime(CACurrentMediaTime() - timeOffset.seconds());
2938
2939     String animationID = animationIdentifier(animationName, property, index, subIndex);
2940
2941     layer->removeAnimationForKey(animationID);
2942     layer->addAnimationForKey(animationID, caAnim);
2943
2944     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
2945         for (auto& clone : *layerCloneMap) {
2946             // Skip immediate replicas, since they move with the original.
2947             if (m_replicaLayer && isReplicatedRootClone(clone.key))
2948                 continue;
2949
2950             clone.value->removeAnimationForKey(animationID);
2951             clone.value->addAnimationForKey(animationID, caAnim);
2952         }
2953     }
2954 }
2955
2956 // Workaround for <rdar://problem/7311367>
2957 static void bug7311367Workaround(PlatformCALayer* transformLayer, const TransformationMatrix& transform)
2958 {
2959     if (!transformLayer)
2960         return;
2961
2962     TransformationMatrix caTransform = transform;
2963     caTransform.setM41(caTransform.m41() + 1);
2964     transformLayer->setTransform(caTransform);
2965
2966     caTransform.setM41(caTransform.m41() - 1);
2967     transformLayer->setTransform(caTransform);
2968 }
2969
2970 bool GraphicsLayerCA::removeCAAnimationFromLayer(AnimatedPropertyID property, const String& animationName, int index, int subIndex)
2971 {
2972     PlatformCALayer* layer = animatedLayer(property);
2973
2974     String animationID = animationIdentifier(animationName, property, index, subIndex);
2975
2976     if (!layer->animationForKey(animationID))
2977         return false;
2978     
2979     layer->removeAnimationForKey(animationID);
2980     bug7311367Workaround(m_structuralLayer.get(), transform());
2981
2982     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
2983         for (auto& clone : *layerCloneMap) {
2984             // Skip immediate replicas, since they move with the original.
2985             if (m_replicaLayer && isReplicatedRootClone(clone.key))
2986                 continue;
2987
2988             clone.value->removeAnimationForKey(animationID);
2989         }
2990     }
2991     return true;
2992 }
2993
2994 void GraphicsLayerCA::pauseCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, int subIndex, Seconds timeOffset)
2995 {
2996     PlatformCALayer* layer = animatedLayer(property);
2997
2998     String animationID = animationIdentifier(animationName, property, index, subIndex);
2999
3000     RefPtr<PlatformCAAnimation> curAnim = layer->animationForKey(animationID);
3001     if (!curAnim)
3002         return;
3003
3004     // Animations on the layer are immutable, so we have to clone and modify.
3005     RefPtr<PlatformCAAnimation> newAnim = curAnim->copy();
3006
3007     newAnim->setSpeed(0);
3008     newAnim->setTimeOffset(timeOffset.seconds());
3009     
3010     layer->addAnimationForKey(animationID, *newAnim); // This will replace the running animation.
3011
3012     // Pause the animations on the clones too.
3013     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
3014         for (auto& clone : *layerCloneMap) {
3015             // Skip immediate replicas, since they move with the original.
3016             if (m_replicaLayer && isReplicatedRootClone(clone.key))
3017                 continue;
3018             clone.value->addAnimationForKey(animationID, *newAnim);
3019         }
3020     }
3021 }
3022
3023 void GraphicsLayerCA::seekCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, int subIndex, Seconds timeOffset)
3024 {
3025     // FIXME: this can be refactored a fair bit or merged with pauseCAAnimationOnLayer() with an operation flag.
3026     PlatformCALayer* layer = animatedLayer(property);
3027
3028     String animationID = animationIdentifier(animationName, property, index, subIndex);
3029
3030     RefPtr<PlatformCAAnimation> currentAnimation = layer->animationForKey(animationID);
3031     if (!currentAnimation)
3032         return;
3033
3034     // Animations on the layer are immutable, so we have to clone and modify.
3035     RefPtr<PlatformCAAnimation> newAnim = currentAnimation->copy();
3036
3037     newAnim->setBeginTime(CACurrentMediaTime());
3038     newAnim->setTimeOffset(timeOffset.seconds());
3039
3040     layer->addAnimationForKey(animationID, *newAnim); // This will replace the running animation.
3041
3042     // Pause the animations on the clones too.
3043     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
3044         for (auto& clone : *layerCloneMap) {
3045             // Skip immediate replicas, since they move with the original.
3046             if (m_replicaLayer && isReplicatedRootClone(clone.key))
3047                 continue;
3048             clone.value->addAnimationForKey(animationID, *newAnim);
3049         }
3050     }
3051 }
3052
3053 void GraphicsLayerCA::repaintLayerDirtyRects()
3054 {
3055     if (m_needsFullRepaint) {
3056         ASSERT(!m_dirtyRects.size());
3057         m_layer->setNeedsDisplay();
3058         m_needsFullRepaint = false;
3059         return;
3060     }
3061
3062     for (auto& dirtyRect : m_dirtyRects)
3063         m_layer->setNeedsDisplayInRect(dirtyRect);
3064     
3065     m_dirtyRects.clear();
3066 }
3067
3068 void GraphicsLayerCA::updateContentsNeedsDisplay()
3069 {
3070     if (m_contentsLayer)
3071         m_contentsLayer->setNeedsDisplay();
3072 }
3073
3074 bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, Seconds timeOffset)
3075 {
3076     ASSERT(valueList.property() != AnimatedPropertyTransform && (!supportsAcceleratedFilterAnimations() || valueList.property() != AnimatedPropertyFilter));
3077
3078     bool isKeyframe = valueList.size() > 2;
3079     bool valuesOK;
3080     
3081     bool additive = false;
3082     int animationIndex = 0;
3083     
3084     RefPtr<PlatformCAAnimation> caAnimation;
3085
3086     if (isKeyframe) {
3087         caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
3088         valuesOK = setAnimationKeyframes(valueList, animation, caAnimation.get());
3089     } else {
3090         if (animation->timingFunction()->isSpringTimingFunction())
3091             caAnimation = createSpringAnimation(animation, propertyIdToString(valueList.property()), additive);
3092         else
3093             caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
3094         valuesOK = setAnimationEndpoints(valueList, animation, caAnimation.get());
3095     }
3096
3097     if (!valuesOK)
3098         return false;
3099
3100     appendToUncommittedAnimations(LayerPropertyAnimation(caAnimation.releaseNonNull(), animationName, valueList.property(), animationIndex, 0, timeOffset));
3101
3102     return true;
3103 }
3104
3105 bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const TransformOperations* operations, const Animation* animation, const String& animationName, const FloatSize& boxSize, int animationIndex, Seconds timeOffset, bool isMatrixAnimation)
3106 {
3107     TransformOperation::OperationType transformOp = isMatrixAnimation ? TransformOperation::MATRIX_3D : operations->operations().at(animationIndex)->type();
3108 #if !PLATFORM(WIN) && !HAVE(CA_WHERE_ADDITIVE_TRANSFORMS_ARE_REVERSED)
3109     bool additive = animationIndex > 0;
3110 #else
3111     int numAnimations = isMatrixAnimation ? 1 : operations->size();
3112     bool additive = animationIndex < numAnimations - 1;
3113 #endif
3114     bool isKeyframe = valueList.size() > 2;
3115
3116     RefPtr<PlatformCAAnimation> caAnimation;
3117     bool validMatrices = true;
3118     if (isKeyframe) {
3119         caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
3120         validMatrices = setTransformAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
3121     } else {
3122         if (animation->timingFunction()->isSpringTimingFunction())
3123             caAnimation = createSpringAnimation(animation, propertyIdToString(valueList.property()), additive);
3124         else
3125             caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
3126         validMatrices = setTransformAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
3127     }
3128     
3129     if (!validMatrices)
3130         return false;
3131
3132     appendToUncommittedAnimations(LayerPropertyAnimation(caAnimation.releaseNonNull(), animationName, valueList.property(), animationIndex, 0, timeOffset));
3133     return true;
3134 }
3135
3136 bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, Seconds timeOffset, const FloatSize& boxSize)
3137 {
3138     ASSERT(valueList.property() == AnimatedPropertyTransform);
3139
3140     bool hasBigRotation;
3141     int listIndex = validateTransformOperations(valueList, hasBigRotation);
3142     const TransformOperations* operations = (listIndex >= 0) ? &static_cast<const TransformAnimationValue&>(valueList.at(listIndex)).value() : 0;
3143
3144     bool validMatrices = true;
3145
3146     // If function lists don't match we do a matrix animation, otherwise we do a component hardware animation.
3147     bool isMatrixAnimation = listIndex < 0;
3148     int numAnimations = isMatrixAnimation ? 1 : operations->size();
3149
3150 #if !PLATFORM(WIN) && !HAVE(CA_WHERE_ADDITIVE_TRANSFORMS_ARE_REVERSED)
3151     for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
3152 #else
3153     // Some versions of CA require animation lists to be applied in reverse order (<rdar://problem/43908047> and <rdar://problem/9112233>).
3154     for (int animationIndex = numAnimations - 1; animationIndex >= 0; --animationIndex) {
3155 #endif
3156         if (!appendToUncommittedAnimations(valueList, operations, animation, animationName, boxSize, animationIndex, timeOffset, isMatrixAnimation)) {
3157             validMatrices = false;
3158             break;
3159         }
3160     }
3161
3162     return validMatrices;
3163 }
3164
3165 bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const FilterOperation* operation, const Animation* animation, const String& animationName, int animationIndex, Seconds timeOffset)
3166 {
3167     bool isKeyframe = valueList.size() > 2;
3168     
3169     FilterOperation::OperationType filterOp = operation->type();
3170     int numAnimatedProperties = PlatformCAFilters::numAnimatedFilterProperties(filterOp);
3171     
3172     // Each filter might need to animate multiple properties, each with their own keyPath. The keyPath is always of the form:
3173     //
3174     //      filter.filter_<animationIndex>.<filterPropertyName>
3175     //
3176     // PlatformCAAnimation tells us how many properties each filter has and we iterate that many times and create an animation
3177     // for each. This internalFilterPropertyIndex gets passed to PlatformCAAnimation so it can properly create the property animation
3178     // values.
3179     for (int internalFilterPropertyIndex = 0; internalFilterPropertyIndex < numAnimatedProperties; ++internalFilterPropertyIndex) {
3180         bool valuesOK;
3181         RefPtr<PlatformCAAnimation> caAnimation;
3182         String keyPath = makeString("filters.filter_", animationIndex, '.', PlatformCAFilters::animatedFilterPropertyName(filterOp, internalFilterPropertyIndex));
3183         
3184         if (isKeyframe) {
3185             caAnimation = createKeyframeAnimation(animation, keyPath, false);
3186             valuesOK = setFilterAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex, filterOp);
3187         } else {
3188             caAnimation = createBasicAnimation(animation, keyPath, false);
3189             valuesOK = setFilterAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex);
3190         }
3191         
3192         ASSERT(valuesOK);
3193
3194         appendToUncommittedAnimations(LayerPropertyAnimation(caAnimation.releaseNonNull(), animationName, valueList.property(), animationIndex, internalFilterPropertyIndex, timeOffset));
3195     }
3196
3197     return true;
3198 }
3199
3200 void GraphicsLayerCA::appendToUncommittedAnimations(LayerPropertyAnimation&& animation)
3201 {
3202     ensureLayerAnimations();
3203
3204     // Since we're adding a new animation, make sure we clear any pending AnimationProcessingAction for this animation
3205     // as these are applied after we've committed new animations.
3206     m_animations->animationsToProcess.remove(animation.m_name);
3207
3208     m_animations->uncomittedAnimations.append(WTFMove(animation));
3209 }
3210
3211 bool GraphicsLayerCA::createFilterAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, Seconds timeOffset)
3212 {
3213 #if ENABLE(FILTERS_LEVEL_2)
3214     ASSERT(valueList.property() == AnimatedPropertyFilter || valueList.property() == AnimatedPropertyWebkitBackdropFilter);
3215 #else
3216     ASSERT(valueList.property() == AnimatedPropertyFilter);
3217 #endif
3218
3219     int listIndex = validateFilterOperations(valueList);
3220     if (listIndex < 0)
3221         return false;
3222
3223     const FilterOperations& operations = static_cast<const FilterAnimationValue&>(valueList.at(listIndex)).value();
3224     // Make sure the platform layer didn't fallback to using software filter compositing instead.
3225     if (!filtersCanBeComposited(operations))
3226         return false;
3227
3228     int numAnimations = operations.size();
3229
3230     // FIXME: We can't currently hardware animate shadows.
3231     for (int i = 0; i < numAnimations; ++i) {
3232         if (operations.at(i)->type() == FilterOperation::DROP_SHADOW)
3233             return false;
3234     }
3235
3236     for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
3237         if (!appendToUncommittedAnimations(valueList, operations.operations().at(animationIndex).get(), animation, animationName, animationIndex, timeOffset))
3238             return false;
3239     }
3240
3241     return true;
3242 }
3243
3244 Ref<PlatformCAAnimation> GraphicsLayerCA::createBasicAnimation(const Animation* anim, const String& keyPath, bool additive)
3245 {
3246     auto basicAnim = createPlatformCAAnimation(PlatformCAAnimation::Basic, keyPath);
3247     setupAnimation(basicAnim.ptr(), anim, additive);
3248     return basicAnim;
3249 }
3250
3251 Ref<PlatformCAAnimation> GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, const String& keyPath, bool additive)
3252 {
3253     auto keyframeAnim = createPlatformCAAnimation(PlatformCAAnimation::Keyframe, keyPath);
3254     setupAnimation(keyframeAnim.ptr(), anim, additive);
3255     return keyframeAnim;
3256 }
3257
3258 Ref<PlatformCAAnimation> GraphicsLayerCA::createSpringAnimation(const Animation* anim, const String& keyPath, bool additive)
3259 {
3260     auto basicAnim = createPlatformCAAnimation(PlatformCAAnimation::Spring, keyPath);
3261     setupAnimation(basicAnim.ptr(), anim, additive);
3262     return basicAnim;
3263 }
3264
3265 void GraphicsLayerCA::setupAnimation(PlatformCAAnimation* propertyAnim, const Animation* anim, bool additive)
3266 {
3267     double duration = anim->duration();
3268     if (duration <= 0)
3269         duration = cAnimationAlmostZeroDuration;
3270
3271     float repeatCount = anim->iterationCount();
3272     if (repeatCount == Animation::IterationCountInfinite)
3273         repeatCount = std::numeric_limits<float>::max();
3274     else if (anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse)
3275         repeatCount /= 2;
3276
3277     PlatformCAAnimation::FillModeType fillMode = PlatformCAAnimation::NoFillMode;
3278     switch (anim->fillMode()) {
3279     case AnimationFillMode::None:
3280         fillMode = PlatformCAAnimation::Forwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash.
3281         break;
3282     case AnimationFillMode::Backwards:
3283         fillMode = PlatformCAAnimation::Both; // Use "both" rather than "backwards" because the style system will remove the animation when it is finished. This avoids a flash.
3284         break;
3285     case AnimationFillMode::Forwards:
3286         fillMode = PlatformCAAnimation::Forwards;
3287         break;
3288     case AnimationFillMode::Both:
3289         fillMode = PlatformCAAnimation::Both;
3290         break;
3291     }
3292
3293     propertyAnim->setDuration(duration);
3294     propertyAnim->setRepeatCount(repeatCount);
3295     propertyAnim->setAutoreverses(anim->direction() == Animation::AnimationDirectionAlternate || anim->direction() == Animation::AnimationDirectionAlternateReverse);
3296     propertyAnim->setRemovedOnCompletion(false);
3297     propertyAnim->setAdditive(additive);
3298     propertyAnim->setFillMode(fillMode);
3299 }
3300
3301 const TimingFunction& GraphicsLayerCA::timingFunctionForAnimationValue(const AnimationValue& animValue, const Animation& anim)
3302 {
3303     if (animValue.timingFunction())
3304         return *animValue.timingFunction();
3305     if (anim.isTimingFunctionSet())
3306         return *anim.timingFunction();
3307     return CubicBezierTimingFunction::defaultTimingFunction();
3308 }
3309
3310 bool GraphicsLayerCA::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim)
3311 {
3312     bool forwards = animation->directionIsForwards();
3313
3314     unsigned fromIndex = !forwards;
3315     unsigned toIndex = forwards;
3316     
3317     switch (valueList.property()) {
3318     case AnimatedPropertyOpacity: {
3319         basicAnim->setFromValue(static_cast<const FloatAnimationValue&>(valueList.at(fromIndex)).value());
3320         basicAnim->setToValue(static_cast<const FloatAnimationValue&>(valueList.at(toIndex)).value());
3321         break;
3322     }
3323     default:
3324         ASSERT_NOT_REACHED(); // we don't animate color yet
3325         break;