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