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