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