2011-04-27 Darin Adler <darin@apple.com>
[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 COMPUTER, 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 #if USE(ACCELERATED_COMPOSITING)
29
30 #include "GraphicsLayerCA.h"
31
32 #include "Animation.h"
33 #include "FloatConversion.h"
34 #include "FloatRect.h"
35 #include "PlatformCALayer.h"
36 #include "PlatformString.h"
37 #include "RotateTransformOperation.h"
38 #include "ScaleTransformOperation.h"
39 #include "SystemTime.h"
40 #include "TranslateTransformOperation.h"
41 #include <QuartzCore/CATransform3D.h>
42 #include <limits.h>
43 #include <wtf/CurrentTime.h>
44 #include <wtf/text/StringConcatenate.h>
45
46 using namespace std;
47
48 #define HAVE_MODERN_QUARTZCORE (!defined(BUILDING_ON_LEOPARD))
49
50 namespace WebCore {
51
52 // The threshold width or height above which a tiled layer will be used. This should be
53 // large enough to avoid tiled layers for most GraphicsLayers, but less than the OpenGL
54 // texture size limit on all supported hardware.
55 static const int cMaxPixelDimension = 2000;
56
57 // If we send a duration of 0 to CA, then it will use the default duration
58 // of 250ms. So send a very small value instead.
59 static const float cAnimationAlmostZeroDuration = 1e-3f;
60
61 static bool isTransformTypeTransformationMatrix(TransformOperation::OperationType transformType)
62 {
63     switch (transformType) {
64     case TransformOperation::SKEW_X:
65     case TransformOperation::SKEW_Y:
66     case TransformOperation::SKEW:
67     case TransformOperation::MATRIX:
68     case TransformOperation::ROTATE_3D:
69     case TransformOperation::MATRIX_3D:
70     case TransformOperation::PERSPECTIVE:
71     case TransformOperation::IDENTITY:
72     case TransformOperation::NONE:
73         return true;
74     default:
75         return false;
76     }
77 }
78
79 static bool isTransformTypeFloatPoint3D(TransformOperation::OperationType transformType)
80 {
81     switch (transformType) {
82     case TransformOperation::SCALE:
83     case TransformOperation::SCALE_3D:
84     case TransformOperation::TRANSLATE:
85     case TransformOperation::TRANSLATE_3D:
86         return true;
87     default:
88         return false;
89     }
90 }
91
92 static bool isTransformTypeNumber(TransformOperation::OperationType transformType)
93 {
94     return !isTransformTypeTransformationMatrix(transformType) && !isTransformTypeFloatPoint3D(transformType);
95 }
96
97 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, float& value)
98 {
99     switch (transformType) {
100     case TransformOperation::ROTATE:
101     case TransformOperation::ROTATE_X:
102     case TransformOperation::ROTATE_Y:
103         value = transformOp ? narrowPrecisionToFloat(deg2rad(static_cast<const RotateTransformOperation*>(transformOp)->angle())) : 0;
104         break;
105     case TransformOperation::SCALE_X:
106         value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1;
107         break;
108     case TransformOperation::SCALE_Y:
109         value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1;
110         break;
111     case TransformOperation::SCALE_Z:
112         value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1;
113         break;
114     case TransformOperation::TRANSLATE_X:
115         value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0;
116         break;
117     case TransformOperation::TRANSLATE_Y:
118         value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0;
119         break;
120     case TransformOperation::TRANSLATE_Z:
121         value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0;
122         break;
123     default:
124         break;
125     }
126 }
127
128 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, FloatPoint3D& value)
129 {
130     switch (transformType) {
131     case TransformOperation::SCALE:
132     case TransformOperation::SCALE_3D:
133         value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1);
134         value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1);
135         value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1);
136         break;
137     case TransformOperation::TRANSLATE:
138     case TransformOperation::TRANSLATE_3D:
139         value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0);
140         value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0);
141         value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0);
142         break;
143     default:
144         break;
145     }
146 }
147
148 static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, TransformationMatrix& value)
149 {
150     switch (transformType) {
151     case TransformOperation::SKEW_X:
152     case TransformOperation::SKEW_Y:
153     case TransformOperation::SKEW:
154     case TransformOperation::MATRIX:
155     case TransformOperation::ROTATE_3D:
156     case TransformOperation::MATRIX_3D:
157     case TransformOperation::PERSPECTIVE:
158     case TransformOperation::IDENTITY:
159     case TransformOperation::NONE:
160         if (transformOp)
161             transformOp->apply(value, size);
162         else
163             value.makeIdentity();
164         break;
165     default:
166         break;
167     }
168 }
169
170 #if HAVE_MODERN_QUARTZCORE
171 static PlatformCAAnimation::ValueFunctionType getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
172 {
173     // Use literal strings to avoid link-time dependency on those symbols.
174     switch (transformType) {
175     case TransformOperation::ROTATE_X:
176         return PlatformCAAnimation::RotateX;
177     case TransformOperation::ROTATE_Y:
178         return PlatformCAAnimation::RotateY;
179     case TransformOperation::ROTATE:
180         return PlatformCAAnimation::RotateZ;
181     case TransformOperation::SCALE_X:
182         return PlatformCAAnimation::ScaleX;
183     case TransformOperation::SCALE_Y:
184         return PlatformCAAnimation::ScaleY;
185     case TransformOperation::SCALE_Z:
186         return PlatformCAAnimation::ScaleZ;
187     case TransformOperation::TRANSLATE_X:
188         return PlatformCAAnimation::TranslateX;
189     case TransformOperation::TRANSLATE_Y:
190         return PlatformCAAnimation::TranslateY;
191     case TransformOperation::TRANSLATE_Z:
192         return PlatformCAAnimation::TranslateZ;
193     case TransformOperation::SCALE:
194     case TransformOperation::SCALE_3D:
195         return PlatformCAAnimation::Scale;
196     case TransformOperation::TRANSLATE:
197     case TransformOperation::TRANSLATE_3D:
198         return PlatformCAAnimation::Translate;
199     default:
200         return PlatformCAAnimation::NoValueFunction;
201     }
202 }
203 #endif
204
205 static String propertyIdToString(AnimatedPropertyID property)
206 {
207     switch (property) {
208     case AnimatedPropertyWebkitTransform:
209         return "transform";
210     case AnimatedPropertyOpacity:
211         return "opacity";
212     case AnimatedPropertyBackgroundColor:
213         return "backgroundColor";
214     case AnimatedPropertyInvalid:
215         ASSERT_NOT_REACHED();
216     }
217     ASSERT_NOT_REACHED();
218     return "";
219 }
220
221 static String animationIdentifier(const String& animationName, AnimatedPropertyID property, int index)
222 {
223     return makeString(animationName, '_', String::number(property), '_', String::number(index));
224 }
225
226 static bool animationHasStepsTimingFunction(const KeyframeValueList& valueList, const Animation* anim)
227 {
228     if (anim->timingFunction()->isStepsTimingFunction())
229         return true;
230     
231     for (unsigned i = 0; i < valueList.size(); ++i) {
232         const TimingFunction* timingFunction = valueList.at(i)->timingFunction();
233         if (timingFunction && timingFunction->isStepsTimingFunction())
234             return true;
235     }
236
237     return false;
238 }
239
240 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
241 {
242     return adoptPtr(new GraphicsLayerCA(client));
243 }
244
245 GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client)
246     : GraphicsLayer(client)
247     , m_contentsLayerPurpose(NoContentsLayer)
248     , m_contentsLayerHasBackgroundColor(false)
249     , m_uncommittedChanges(NoChange)
250     , m_contentsScale(1)
251     , m_allowTiledLayer(true)
252 {
253     m_layer = PlatformCALayer::create(PlatformCALayer::LayerTypeWebLayer, this);
254
255 #if !HAVE_MODERN_QUARTZCORE
256     setContentsOrientation(defaultContentsOrientation());
257 #endif
258
259     updateDebugIndicators();
260 }
261
262 GraphicsLayerCA::~GraphicsLayerCA()
263 {
264     // We release our references to the PlatformCALayers here, but do not actively unparent them,
265     // since that will cause a commit and break our batched commit model. The layers will
266     // get released when the rootmost modified GraphicsLayerCA rebuilds its child layers.
267     
268     // Clean up the layer.
269     if (m_layer)
270         m_layer->setOwner(0);
271     
272     if (m_contentsLayer)
273         m_contentsLayer->setOwner(0);
274         
275     if (m_structuralLayer)
276         m_structuralLayer->setOwner(0);
277     
278     removeCloneLayers();
279 }
280
281 void GraphicsLayerCA::setName(const String& name)
282 {
283     String longName = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer.get(), this) + name;
284     GraphicsLayer::setName(longName);
285     noteLayerPropertyChanged(NameChanged);
286 }
287
288 PlatformLayer* GraphicsLayerCA::platformLayer() const
289 {
290     return primaryLayer()->platformLayer();
291 }
292
293 bool GraphicsLayerCA::setChildren(const Vector<GraphicsLayer*>& children)
294 {
295     bool childrenChanged = GraphicsLayer::setChildren(children);
296     if (childrenChanged)
297         noteSublayersChanged();
298     
299     return childrenChanged;
300 }
301
302 void GraphicsLayerCA::addChild(GraphicsLayer* childLayer)
303 {
304     GraphicsLayer::addChild(childLayer);
305     noteSublayersChanged();
306 }
307
308 void GraphicsLayerCA::addChildAtIndex(GraphicsLayer* childLayer, int index)
309 {
310     GraphicsLayer::addChildAtIndex(childLayer, index);
311     noteSublayersChanged();
312 }
313
314 void GraphicsLayerCA::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
315 {
316     GraphicsLayer::addChildBelow(childLayer, sibling);
317     noteSublayersChanged();
318 }
319
320 void GraphicsLayerCA::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
321 {
322     GraphicsLayer::addChildAbove(childLayer, sibling);
323     noteSublayersChanged();
324 }
325
326 bool GraphicsLayerCA::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
327 {
328     if (GraphicsLayer::replaceChild(oldChild, newChild)) {
329         noteSublayersChanged();
330         return true;
331     }
332     return false;
333 }
334
335 void GraphicsLayerCA::removeFromParent()
336 {
337     if (m_parent)
338         static_cast<GraphicsLayerCA*>(m_parent)->noteSublayersChanged();
339     GraphicsLayer::removeFromParent();
340 }
341
342 void GraphicsLayerCA::setMaskLayer(GraphicsLayer* layer)
343 {
344     if (layer == m_maskLayer)
345         return;
346
347     GraphicsLayer::setMaskLayer(layer);
348     noteLayerPropertyChanged(MaskLayerChanged);
349
350     propagateLayerChangeToReplicas();
351     
352     if (m_replicatedLayer)
353         static_cast<GraphicsLayerCA*>(m_replicatedLayer)->propagateLayerChangeToReplicas();
354 }
355
356 void GraphicsLayerCA::setReplicatedLayer(GraphicsLayer* layer)
357 {
358     if (layer == m_replicatedLayer)
359         return;
360
361     GraphicsLayer::setReplicatedLayer(layer);
362     noteLayerPropertyChanged(ReplicatedLayerChanged);
363 }
364
365 void GraphicsLayerCA::setReplicatedByLayer(GraphicsLayer* layer)
366 {
367     if (layer == m_replicaLayer)
368         return;
369
370     GraphicsLayer::setReplicatedByLayer(layer);
371     noteSublayersChanged();
372     noteLayerPropertyChanged(ReplicatedLayerChanged);
373 }
374
375 void GraphicsLayerCA::setPosition(const FloatPoint& point)
376 {
377     if (point == m_position)
378         return;
379
380     GraphicsLayer::setPosition(point);
381     noteLayerPropertyChanged(PositionChanged);
382 }
383
384 void GraphicsLayerCA::setAnchorPoint(const FloatPoint3D& point)
385 {
386     if (point == m_anchorPoint)
387         return;
388
389     GraphicsLayer::setAnchorPoint(point);
390     noteLayerPropertyChanged(AnchorPointChanged);
391 }
392
393 void GraphicsLayerCA::setSize(const FloatSize& size)
394 {
395     if (size == m_size)
396         return;
397
398     GraphicsLayer::setSize(size);
399     noteLayerPropertyChanged(SizeChanged);
400 }
401
402 void GraphicsLayerCA::setTransform(const TransformationMatrix& t)
403 {
404     if (t == m_transform)
405         return;
406
407     GraphicsLayer::setTransform(t);
408     noteLayerPropertyChanged(TransformChanged);
409 }
410
411 void GraphicsLayerCA::setChildrenTransform(const TransformationMatrix& t)
412 {
413     if (t == m_childrenTransform)
414         return;
415
416     GraphicsLayer::setChildrenTransform(t);
417     noteLayerPropertyChanged(ChildrenTransformChanged);
418 }
419
420 void GraphicsLayerCA::moveOrCopyLayerAnimation(MoveOrCopy operation, const String& animationIdentifier, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
421 {
422     RefPtr<PlatformCAAnimation> anim = fromLayer->animationForKey(animationIdentifier);
423     if (!anim)
424         return;
425
426     switch (operation) {
427     case Move:
428         fromLayer->removeAnimationForKey(animationIdentifier);
429         toLayer->addAnimationForKey(animationIdentifier, anim.get());
430         break;
431
432     case Copy:
433         toLayer->addAnimationForKey(animationIdentifier, anim.get());
434         break;
435     }
436 }
437
438 void GraphicsLayerCA::moveOrCopyAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
439 {
440     // Look for running animations affecting this property.
441     AnimationsMap::const_iterator end = m_runningAnimations.end();
442     for (AnimationsMap::const_iterator it = m_runningAnimations.begin(); it != end; ++it) {
443         const Vector<LayerPropertyAnimation>& propertyAnimations = it->second;
444         size_t numAnimations = propertyAnimations.size();
445         for (size_t i = 0; i < numAnimations; ++i) {
446             const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
447             if (currAnimation.m_property == property)
448                 moveOrCopyLayerAnimation(operation, animationIdentifier(currAnimation.m_name, currAnimation.m_property, currAnimation.m_index), fromLayer, toLayer);
449         }
450     }
451 }
452
453 void GraphicsLayerCA::setPreserves3D(bool preserves3D)
454 {
455     if (preserves3D == m_preserves3D)
456         return;
457
458     GraphicsLayer::setPreserves3D(preserves3D);
459     noteLayerPropertyChanged(Preserves3DChanged);
460 }
461
462 void GraphicsLayerCA::setMasksToBounds(bool masksToBounds)
463 {
464     if (masksToBounds == m_masksToBounds)
465         return;
466
467     GraphicsLayer::setMasksToBounds(masksToBounds);
468     noteLayerPropertyChanged(MasksToBoundsChanged);
469 }
470
471 void GraphicsLayerCA::setDrawsContent(bool drawsContent)
472 {
473     if (drawsContent == m_drawsContent)
474         return;
475
476     GraphicsLayer::setDrawsContent(drawsContent);
477     noteLayerPropertyChanged(DrawsContentChanged);
478 }
479
480 void GraphicsLayerCA::setAcceleratesDrawing(bool acceleratesDrawing)
481 {
482     if (acceleratesDrawing == m_acceleratesDrawing)
483         return;
484
485     GraphicsLayer::setAcceleratesDrawing(acceleratesDrawing);
486     noteLayerPropertyChanged(AcceleratesDrawingChanged);
487 }
488
489 void GraphicsLayerCA::setAllowTiledLayer(bool allowTiledLayer)
490 {
491     if (allowTiledLayer == m_allowTiledLayer)
492         return;
493
494     m_allowTiledLayer = allowTiledLayer;
495     
496     // Handling this as a SizeChanged will cause use to switch in or out of tiled layer as needed
497     noteLayerPropertyChanged(SizeChanged);
498 }
499
500 void GraphicsLayerCA::setBackgroundColor(const Color& color)
501 {
502     if (m_backgroundColorSet && m_backgroundColor == color)
503         return;
504
505     GraphicsLayer::setBackgroundColor(color);
506
507     m_contentsLayerHasBackgroundColor = true;
508     noteLayerPropertyChanged(BackgroundColorChanged);
509 }
510
511 void GraphicsLayerCA::clearBackgroundColor()
512 {
513     if (!m_backgroundColorSet)
514         return;
515
516     GraphicsLayer::clearBackgroundColor();
517     m_contentsLayerHasBackgroundColor = false;
518     noteLayerPropertyChanged(BackgroundColorChanged);
519 }
520
521 void GraphicsLayerCA::setContentsOpaque(bool opaque)
522 {
523     if (m_contentsOpaque == opaque)
524         return;
525
526     GraphicsLayer::setContentsOpaque(opaque);
527     noteLayerPropertyChanged(ContentsOpaqueChanged);
528 }
529
530 void GraphicsLayerCA::setBackfaceVisibility(bool visible)
531 {
532     if (m_backfaceVisibility == visible)
533         return;
534     
535     GraphicsLayer::setBackfaceVisibility(visible);
536     noteLayerPropertyChanged(BackfaceVisibilityChanged);
537 }
538
539 void GraphicsLayerCA::setOpacity(float opacity)
540 {
541     float clampedOpacity = max(0.0f, min(opacity, 1.0f));
542
543     if (clampedOpacity == m_opacity)
544         return;
545
546     GraphicsLayer::setOpacity(clampedOpacity);
547     noteLayerPropertyChanged(OpacityChanged);
548 }
549
550 void GraphicsLayerCA::setNeedsDisplay()
551 {
552     FloatRect hugeRect(-numeric_limits<float>::max() / 2, -numeric_limits<float>::max() / 2,
553                        numeric_limits<float>::max(), numeric_limits<float>::max());
554
555     setNeedsDisplayInRect(hugeRect);
556 }
557
558 void GraphicsLayerCA::setNeedsDisplayInRect(const FloatRect& r)
559 {
560     if (!drawsContent())
561         return;
562
563     FloatRect rect(r);
564     FloatRect layerBounds(FloatPoint(), m_size);
565     rect.intersect(layerBounds);
566     if (rect.isEmpty())
567         return;
568     
569     const size_t maxDirtyRects = 32;
570     
571     for (size_t i = 0; i < m_dirtyRects.size(); ++i) {
572         if (m_dirtyRects[i].contains(rect))
573             return;
574     }
575     
576     if (m_dirtyRects.size() < maxDirtyRects)
577         m_dirtyRects.append(rect);
578     else
579         m_dirtyRects[0].unite(rect);
580
581     noteLayerPropertyChanged(DirtyRectsChanged);
582 }
583
584 void GraphicsLayerCA::setContentsNeedsDisplay()
585 {
586     noteLayerPropertyChanged(ContentsNeedsDisplay);
587 }
588
589 void GraphicsLayerCA::setContentsRect(const IntRect& rect)
590 {
591     if (rect == m_contentsRect)
592         return;
593
594     GraphicsLayer::setContentsRect(rect);
595     noteLayerPropertyChanged(ContentsRectChanged);
596 }
597
598 bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& animationName, double timeOffset)
599 {
600     ASSERT(!animationName.isEmpty());
601
602     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
603         return false;
604
605 #if !HAVE_MODERN_QUARTZCORE
606     // Older versions of QuartzCore do not handle opacity in transform layers properly, so we will
607     // always do software animation in that case.
608     if (valueList.property() == AnimatedPropertyOpacity)
609         return false;
610 #endif
611
612     // CoreAnimation does not handle the steps() timing function. Fall back
613     // to software animation in that case.
614     if (animationHasStepsTimingFunction(valueList, anim))
615         return false;
616
617     bool createdAnimations = false;
618     if (valueList.property() == AnimatedPropertyWebkitTransform)
619         createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, animationName, timeOffset, boxSize);
620     else
621         createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, timeOffset);
622
623     if (createdAnimations)
624         noteLayerPropertyChanged(AnimationChanged);
625         
626     return createdAnimations;
627 }
628
629 void GraphicsLayerCA::pauseAnimation(const String& animationName, double timeOffset)
630 {
631     if (!animationIsRunning(animationName))
632         return;
633
634     AnimationsToProcessMap::iterator it = m_animationsToProcess.find(animationName);
635     if (it != m_animationsToProcess.end()) {
636         AnimationProcessingAction& processingInfo = it->second;
637         // If an animation is scheduled to be removed, don't change the remove to a pause.
638         if (processingInfo.action != Remove)
639             processingInfo.action = Pause;
640     } else
641         m_animationsToProcess.add(animationName, AnimationProcessingAction(Pause, timeOffset));
642
643     noteLayerPropertyChanged(AnimationChanged);
644 }
645
646 void GraphicsLayerCA::removeAnimation(const String& animationName)
647 {
648     if (!animationIsRunning(animationName))
649         return;
650
651     m_animationsToProcess.add(animationName, AnimationProcessingAction(Remove));
652     noteLayerPropertyChanged(AnimationChanged);
653 }
654
655 void GraphicsLayerCA::platformCALayerAnimationStarted(CFTimeInterval startTime)
656 {
657     if (m_client)
658         m_client->notifyAnimationStarted(this, startTime);
659 }
660
661 void GraphicsLayerCA::setContentsToImage(Image* image)
662 {
663     if (image) {
664         CGImageRef newImage = image->nativeImageForCurrentFrame();
665         if (!newImage)
666             return;
667
668         // Check to see if the image changed; we have to do this because the call to
669         // CGImageCreateCopyWithColorSpace() below can create a new image every time.
670         if (m_uncorrectedContentsImage && m_uncorrectedContentsImage.get() == newImage)
671             return;
672         
673         m_uncorrectedContentsImage = newImage;
674         m_pendingContentsImage = newImage;
675
676 #if !PLATFORM(WIN)
677         CGColorSpaceRef colorSpace = CGImageGetColorSpace(m_pendingContentsImage.get());
678
679         static CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
680         if (colorSpace && CFEqual(colorSpace, deviceRGB)) {
681             // CoreGraphics renders images tagged with DeviceRGB using the color space of the main display. When we hand such
682             // images to CA we need to tag them similarly so CA rendering matches CG rendering.
683             static CGColorSpaceRef genericRGB = CGDisplayCopyColorSpace(kCGDirectMainDisplay);
684             m_pendingContentsImage.adoptCF(CGImageCreateCopyWithColorSpace(m_pendingContentsImage.get(), genericRGB));
685         }
686 #endif
687         m_contentsLayerPurpose = ContentsLayerForImage;
688         if (!m_contentsLayer)
689             noteSublayersChanged();
690     } else {
691         m_uncorrectedContentsImage = 0;
692         m_pendingContentsImage = 0;
693         m_contentsLayerPurpose = NoContentsLayer;
694         if (m_contentsLayer)
695             noteSublayersChanged();
696     }
697
698     noteLayerPropertyChanged(ContentsImageChanged);
699 }
700
701 void GraphicsLayerCA::setContentsToMedia(PlatformLayer* mediaLayer)
702 {
703     if (m_contentsLayer && mediaLayer == m_contentsLayer->platformLayer())
704         return;
705         
706     // FIXME: The passed in layer might be a raw layer or an externally created 
707     // PlatformCALayer. To determine this we attempt to get the
708     // PlatformCALayer pointer. If this returns a null pointer we assume it's
709     // raw. This test might be invalid if the raw layer is, for instance, the
710     // PlatformCALayer is using a user data pointer in the raw layer, and
711     // the creator of the raw layer is using it for some other purpose.
712     // For now we don't support such a case.
713     PlatformCALayer* platformCALayer = PlatformCALayer::platformCALayer(mediaLayer);
714     m_contentsLayer = mediaLayer ? (platformCALayer ? platformCALayer : PlatformCALayer::create(mediaLayer, this)) : 0;
715     m_contentsLayerPurpose = mediaLayer ? ContentsLayerForMedia : NoContentsLayer;
716
717     noteSublayersChanged();
718     noteLayerPropertyChanged(ContentsMediaLayerChanged);
719 }
720
721 void GraphicsLayerCA::setContentsToCanvas(PlatformLayer* canvasLayer)
722 {
723     if (m_contentsLayer && canvasLayer == m_contentsLayer->platformLayer())
724         return;
725     
726     // Create the PlatformCALayer to wrap the incoming layer
727     m_contentsLayer = canvasLayer ? PlatformCALayer::create(canvasLayer, this) : 0;
728     
729     m_contentsLayerPurpose = canvasLayer ? ContentsLayerForCanvas : NoContentsLayer;
730
731     noteSublayersChanged();
732     noteLayerPropertyChanged(ContentsCanvasLayerChanged);
733 }
734     
735 void GraphicsLayerCA::layerDidDisplay(PlatformLayer* layer)
736 {
737     PlatformCALayer* currentLayer = PlatformCALayer::platformCALayer(layer);
738     PlatformCALayer* sourceLayer;
739     LayerMap* layerCloneMap;
740
741     if (currentLayer == m_layer) {
742         sourceLayer = m_layer.get();
743         layerCloneMap = m_layerClones.get();
744     } else if (currentLayer == m_contentsLayer) {
745         sourceLayer = m_contentsLayer.get();
746         layerCloneMap = m_contentsLayerClones.get();
747     } else
748         return;
749
750     if (layerCloneMap) {
751         LayerMap::const_iterator end = layerCloneMap->end();
752         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
753             PlatformCALayer* currClone = it->second.get();
754             if (!currClone)
755                 continue;
756
757             if (currClone->contents() != sourceLayer->contents())
758                 currClone->setContents(sourceLayer->contents());
759             else
760                 currClone->setContentsChanged();
761         }
762     }
763 }
764
765 void GraphicsLayerCA::syncCompositingState()
766 {
767     recursiveCommitChanges();
768 }
769
770 void GraphicsLayerCA::syncCompositingStateForThisLayerOnly()
771 {
772     commitLayerChangesBeforeSublayers();
773     commitLayerChangesAfterSublayers();
774 }
775
776 void GraphicsLayerCA::recursiveCommitChanges()
777 {
778     commitLayerChangesBeforeSublayers();
779
780     if (m_maskLayer)
781         static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesBeforeSublayers();
782
783     const Vector<GraphicsLayer*>& childLayers = children();
784     size_t numChildren = childLayers.size();
785     for (size_t i = 0; i < numChildren; ++i) {
786         GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
787         curChild->recursiveCommitChanges();
788     }
789
790     if (m_replicaLayer)
791         static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveCommitChanges();
792
793     if (m_maskLayer)
794         static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesAfterSublayers();
795
796     commitLayerChangesAfterSublayers();
797 }
798
799 void GraphicsLayerCA::commitLayerChangesBeforeSublayers()
800 {
801     if (!m_uncommittedChanges)
802         return;
803
804     // Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to
805     if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged))
806         updateStructuralLayer();
807
808     if (m_uncommittedChanges & NameChanged)
809         updateLayerNames();
810
811     if (m_uncommittedChanges & ContentsImageChanged) // Needs to happen before ChildrenChanged
812         updateContentsImage();
813         
814     if (m_uncommittedChanges & ContentsMediaLayerChanged) // Needs to happen before ChildrenChanged
815         updateContentsMediaLayer();
816     
817     if (m_uncommittedChanges & ContentsCanvasLayerChanged) // Needs to happen before ChildrenChanged
818         updateContentsCanvasLayer();
819     
820     if (m_uncommittedChanges & BackgroundColorChanged) // Needs to happen before ChildrenChanged, and after updating image or video
821         updateLayerBackgroundColor();
822
823     if (m_uncommittedChanges & ChildrenChanged)
824         updateSublayerList();
825
826     if (m_uncommittedChanges & PositionChanged)
827         updateLayerPosition();
828     
829     if (m_uncommittedChanges & AnchorPointChanged)
830         updateAnchorPoint();
831     
832     if (m_uncommittedChanges & SizeChanged)
833         updateLayerSize();
834
835     if (m_uncommittedChanges & TransformChanged)
836         updateTransform();
837
838     if (m_uncommittedChanges & ChildrenTransformChanged)
839         updateChildrenTransform();
840     
841     if (m_uncommittedChanges & MasksToBoundsChanged)
842         updateMasksToBounds();
843     
844     if (m_uncommittedChanges & DrawsContentChanged)
845         updateLayerDrawsContent();
846
847     if (m_uncommittedChanges & ContentsOpaqueChanged)
848         updateContentsOpaque();
849
850     if (m_uncommittedChanges & BackfaceVisibilityChanged)
851         updateBackfaceVisibility();
852
853     if (m_uncommittedChanges & OpacityChanged)
854         updateOpacityOnLayer();
855     
856     if (m_uncommittedChanges & AnimationChanged)
857         updateLayerAnimations();
858     
859     if (m_uncommittedChanges & DirtyRectsChanged)
860         repaintLayerDirtyRects();
861     
862     if (m_uncommittedChanges & ContentsRectChanged)
863         updateContentsRect();
864
865     if (m_uncommittedChanges & MaskLayerChanged)
866         updateMaskLayer();
867
868     if (m_uncommittedChanges & ContentsNeedsDisplay)
869         updateContentsNeedsDisplay();
870     
871     if (m_uncommittedChanges & AcceleratesDrawingChanged)
872         updateAcceleratesDrawing();
873     
874     if (m_uncommittedChanges & ContentsScaleChanged)
875         updateContentsScale();
876 }
877
878 void GraphicsLayerCA::commitLayerChangesAfterSublayers()
879 {
880     if (!m_uncommittedChanges)
881         return;
882
883     if (m_uncommittedChanges & ReplicatedLayerChanged)
884         updateReplicatedLayers();
885
886     m_uncommittedChanges = NoChange;
887 }
888
889 void GraphicsLayerCA::updateLayerNames()
890 {
891     switch (structuralLayerPurpose()) {
892     case StructuralLayerForPreserves3D:
893         m_structuralLayer->setName("Transform layer " + name());
894         break;
895     case StructuralLayerForReplicaFlattening:
896         m_structuralLayer->setName("Replica flattening layer " + name());
897         break;
898     case NoStructuralLayer:
899         break;
900     }
901     m_layer->setName(name());
902 }
903
904 void GraphicsLayerCA::updateSublayerList()
905 {
906     PlatformCALayerList newSublayers;
907     const Vector<GraphicsLayer*>& childLayers = children();
908
909     if (m_structuralLayer || m_contentsLayer || childLayers.size() > 0) {
910         if (m_structuralLayer) {
911             // Add the replica layer first.
912             if (m_replicaLayer)
913                 newSublayers.append(static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer());
914             // Add the primary layer. Even if we have negative z-order children, the primary layer always comes behind.
915             newSublayers.append(m_layer);
916         } else if (m_contentsLayer) {
917             // FIXME: add the contents layer in the correct order with negative z-order children.
918             // This does not cause visible rendering issues because currently contents layers are only used
919             // for replaced elements that don't have children.
920             newSublayers.append(m_contentsLayer);
921         }
922         
923         size_t numChildren = childLayers.size();
924         for (size_t i = 0; i < numChildren; ++i) {
925             GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
926             PlatformCALayer* childLayer = curChild->layerForSuperlayer();
927             newSublayers.append(childLayer);
928         }
929
930         for (size_t i = 0; i < newSublayers.size(); --i)
931             newSublayers[i]->removeFromSuperlayer();
932     }
933
934     if (m_structuralLayer) {
935         m_structuralLayer->setSublayers(newSublayers);
936
937         if (m_contentsLayer) {
938             // If we have a transform layer, then the contents layer is parented in the 
939             // primary layer (which is itself a child of the transform layer).
940             m_layer->removeAllSublayers();
941             m_layer->appendSublayer(m_contentsLayer.get());
942         }
943     } else
944         m_layer->setSublayers(newSublayers);
945 }
946
947 void GraphicsLayerCA::updateLayerPosition()
948 {
949     FloatSize usedSize = m_usingTiledLayer ? constrainedSize() : m_size;
950
951     // Position is offset on the layer by the layer anchor point.
952     FloatPoint posPoint(m_position.x() + m_anchorPoint.x() * usedSize.width(),
953                           m_position.y() + m_anchorPoint.y() * usedSize.height());
954     
955     primaryLayer()->setPosition(posPoint);
956
957     if (LayerMap* layerCloneMap = primaryLayerClones()) {
958         LayerMap::const_iterator end = layerCloneMap->end();
959         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
960             FloatPoint clonePosition = posPoint;
961             if (m_replicaLayer && isReplicatedRootClone(it->first)) {
962                 // Maintain the special-case position for the root of a clone subtree,
963                 // which we set up in replicatedLayerRoot().
964                 clonePosition = positionForCloneRootLayer();
965             }
966             it->second->setPosition(clonePosition);
967         }
968     }
969 }
970
971 void GraphicsLayerCA::updateLayerSize()
972 {
973     FloatRect rect(0, 0, m_size.width(), m_size.height());
974     if (m_structuralLayer) {
975         m_structuralLayer->setBounds(rect);
976         
977         if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
978             LayerMap::const_iterator end = layerCloneMap->end();
979             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
980                 it->second->setBounds(rect);
981         }
982
983         // The anchor of the contents layer is always at 0.5, 0.5, so the position is center-relative.
984         CGPoint centerPoint = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
985         m_layer->setPosition(centerPoint);
986
987         if (LayerMap* layerCloneMap = m_layerClones.get()) {
988             LayerMap::const_iterator end = layerCloneMap->end();
989             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
990                 it->second->setPosition(centerPoint);
991         }
992     }
993     
994     bool needTiledLayer = requiresTiledLayer(m_size);
995     if (needTiledLayer != m_usingTiledLayer)
996         swapFromOrToTiledLayer(needTiledLayer);
997     
998     if (m_usingTiledLayer) {
999         FloatSize sizeToUse = constrainedSize();
1000         rect = CGRectMake(0, 0, sizeToUse.width(), sizeToUse.height());
1001     }
1002     
1003     m_layer->setBounds(rect);
1004     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1005         LayerMap::const_iterator end = layerCloneMap->end();
1006         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1007             it->second->setBounds(rect);
1008     }
1009     
1010     // Contents transform may depend on height.
1011     updateContentsTransform();
1012
1013     // Note that we don't resize m_contentsLayer. It's up the caller to do that.
1014
1015     // if we've changed the bounds, we need to recalculate the position
1016     // of the layer, taking anchor point into account.
1017     updateLayerPosition();
1018 }
1019
1020 void GraphicsLayerCA::updateAnchorPoint()
1021 {
1022     primaryLayer()->setAnchorPoint(m_anchorPoint);
1023
1024     if (LayerMap* layerCloneMap = primaryLayerClones()) {
1025         LayerMap::const_iterator end = layerCloneMap->end();
1026         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {   
1027             PlatformCALayer* currLayer = it->second.get();
1028             currLayer->setAnchorPoint(m_anchorPoint);
1029         }
1030     }
1031
1032     updateLayerPosition();
1033 }
1034
1035 void GraphicsLayerCA::updateTransform()
1036 {
1037     primaryLayer()->setTransform(m_transform);
1038
1039     if (LayerMap* layerCloneMap = primaryLayerClones()) {
1040         LayerMap::const_iterator end = layerCloneMap->end();
1041         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1042             PlatformCALayer* currLayer = it->second.get();
1043             if (m_replicaLayer && isReplicatedRootClone(it->first)) {
1044                 // Maintain the special-case transform for the root of a clone subtree,
1045                 // which we set up in replicatedLayerRoot().
1046                 currLayer->setTransform(TransformationMatrix());
1047             } else
1048                 currLayer->setTransform(m_transform);
1049         }
1050     }
1051 }
1052
1053 void GraphicsLayerCA::updateChildrenTransform()
1054 {
1055     primaryLayer()->setSublayerTransform(m_childrenTransform);
1056
1057     if (LayerMap* layerCloneMap = primaryLayerClones()) {
1058         LayerMap::const_iterator end = layerCloneMap->end();
1059         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1060             it->second->setSublayerTransform(m_childrenTransform);
1061     }
1062 }
1063
1064 void GraphicsLayerCA::updateMasksToBounds()
1065 {
1066     m_layer->setMasksToBounds(m_masksToBounds);
1067
1068     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1069         LayerMap::const_iterator end = layerCloneMap->end();
1070         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1071             it->second->setMasksToBounds(m_masksToBounds);
1072     }
1073
1074     updateDebugIndicators();
1075 }
1076
1077 void GraphicsLayerCA::updateContentsOpaque()
1078 {
1079     m_layer.get()->setOpaque(m_contentsOpaque);
1080
1081     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1082         LayerMap::const_iterator end = layerCloneMap->end();
1083         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1084             it->second->setOpaque(m_contentsOpaque);
1085     }
1086 }
1087
1088 void GraphicsLayerCA::updateBackfaceVisibility()
1089 {
1090     if (m_structuralLayer && structuralLayerPurpose() == StructuralLayerForReplicaFlattening) {
1091         m_structuralLayer->setDoubleSided(m_backfaceVisibility);
1092
1093         if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
1094             LayerMap::const_iterator end = layerCloneMap->end();
1095             for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1096                 it->second->setDoubleSided(m_backfaceVisibility);
1097         }
1098     }
1099
1100     m_layer->setDoubleSided(m_backfaceVisibility);
1101
1102     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1103         LayerMap::const_iterator end = layerCloneMap->end();
1104         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
1105             it->second->setDoubleSided(m_backfaceVisibility);
1106     }
1107 }
1108
1109 void GraphicsLayerCA::updateStructuralLayer()
1110 {
1111     ensureStructuralLayer(structuralLayerPurpose());
1112 }
1113
1114 void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose)
1115 {
1116     if (purpose == NoStructuralLayer) {
1117         if (m_structuralLayer) {
1118             // Replace the transformLayer in the parent with this layer.
1119             m_layer->removeFromSuperlayer();
1120  
1121             // If m_layer doesn't have a parent, it means it's the root layer and
1122             // is likely hosted by something that is not expecting to be changed
1123             ASSERT(m_structuralLayer->superlayer());
1124             m_structuralLayer->superlayer()->replaceSublayer(m_structuralLayer.get(), m_layer.get());
1125
1126             moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, m_structuralLayer.get(), m_layer.get());
1127             moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, m_structuralLayer.get(), m_layer.get());
1128
1129             // Release the structural layer.
1130             m_structuralLayer = 0;
1131
1132             // Update the properties of m_layer now that we no longer have a structural layer.
1133             updateLayerPosition();
1134             updateLayerSize();
1135             updateAnchorPoint();
1136             updateTransform();
1137             updateChildrenTransform();
1138
1139             updateSublayerList();
1140             updateOpacityOnLayer();
1141         }
1142         return;
1143     }
1144     
1145     bool structuralLayerChanged = false;
1146     
1147     if (purpose == StructuralLayerForPreserves3D) {
1148         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeTransformLayer)
1149             m_structuralLayer = 0;
1150         
1151         if (!m_structuralLayer) {
1152             m_structuralLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeTransformLayer, this);
1153             structuralLayerChanged = true;
1154         }
1155     } else {
1156         if (m_structuralLayer && m_structuralLayer->layerType() != PlatformCALayer::LayerTypeLayer)
1157             m_structuralLayer = 0;
1158
1159         if (!m_structuralLayer) {
1160             m_structuralLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
1161             structuralLayerChanged = true;
1162         }
1163     }
1164     
1165     if (!structuralLayerChanged)
1166         return;
1167     
1168     updateLayerNames();
1169
1170     // Update the properties of the structural layer.
1171     updateLayerPosition();
1172     updateLayerSize();
1173     updateAnchorPoint();
1174     updateTransform();
1175     updateChildrenTransform();
1176     updateBackfaceVisibility();
1177     
1178     // Set properties of m_layer to their default values, since these are expressed on on the structural layer.
1179     FloatPoint point(m_size.width() / 2.0f, m_size.height() / 2.0f);
1180     FloatPoint3D anchorPoint(0.5f, 0.5f, 0);
1181     m_layer->setPosition(point);
1182     m_layer->setAnchorPoint(anchorPoint);
1183     m_layer->setTransform(TransformationMatrix());
1184     m_layer->setOpacity(1);
1185     if (m_layerClones) {
1186         LayerMap::const_iterator end = m_layerClones->end();
1187         for (LayerMap::const_iterator it = m_layerClones->begin(); it != end; ++it) {
1188             PlatformCALayer* currLayer = it->second.get();
1189             currLayer->setPosition(point);
1190             currLayer->setAnchorPoint(anchorPoint);
1191             currLayer->setTransform(TransformationMatrix());
1192             currLayer->setOpacity(1);
1193         }
1194     }
1195
1196     // Move this layer to be a child of the transform layer.
1197     // If m_layer doesn't have a parent, it means it's the root layer and
1198     // is likely hosted by something that is not expecting to be changed
1199     ASSERT(m_layer->superlayer());
1200     m_layer->superlayer()->replaceSublayer(m_layer.get(), m_structuralLayer.get());
1201     m_structuralLayer->appendSublayer(m_layer.get());
1202
1203     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, m_layer.get(), m_structuralLayer.get());
1204     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, m_layer.get(), m_structuralLayer.get());
1205     
1206     updateSublayerList();
1207     updateOpacityOnLayer();
1208 }
1209
1210 GraphicsLayerCA::StructuralLayerPurpose GraphicsLayerCA::structuralLayerPurpose() const
1211 {
1212     if (preserves3D())
1213         return StructuralLayerForPreserves3D;
1214     
1215     if (isReplicated())
1216         return StructuralLayerForReplicaFlattening;
1217     
1218     return NoStructuralLayer;
1219 }
1220
1221 void GraphicsLayerCA::updateLayerDrawsContent()
1222 {
1223     bool needTiledLayer = requiresTiledLayer(m_size);
1224     if (needTiledLayer != m_usingTiledLayer)
1225         swapFromOrToTiledLayer(needTiledLayer);
1226
1227     if (m_drawsContent)
1228         m_layer->setNeedsDisplay();
1229     else
1230         m_layer->setContents(0);
1231
1232     updateDebugIndicators();
1233 }
1234
1235 void GraphicsLayerCA::updateAcceleratesDrawing()
1236 {
1237     m_layer->setAcceleratesDrawing(m_acceleratesDrawing);
1238 }
1239     
1240 void GraphicsLayerCA::updateLayerBackgroundColor()
1241 {
1242     if (!m_contentsLayer)
1243         return;
1244
1245     // We never create the contents layer just for background color yet.
1246     if (m_backgroundColorSet)
1247         m_contentsLayer->setBackgroundColor(m_backgroundColor);
1248     else
1249         m_contentsLayer->setBackgroundColor(Color::transparent);
1250 }
1251
1252 void GraphicsLayerCA::updateContentsImage()
1253 {
1254     if (m_pendingContentsImage) {
1255         if (!m_contentsLayer.get()) {
1256             m_contentsLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
1257 #ifndef NDEBUG
1258             m_contentsLayer->setName("Image Layer");
1259 #endif
1260             setupContentsLayer(m_contentsLayer.get());
1261             // m_contentsLayer will be parented by updateSublayerList
1262         }
1263
1264         // FIXME: maybe only do trilinear if the image is being scaled down,
1265         // but then what if the layer size changes?
1266 #ifndef BUILDING_ON_LEOPARD
1267         m_contentsLayer->setMinificationFilter(PlatformCALayer::Trilinear);
1268 #endif
1269         m_contentsLayer->setContents(m_pendingContentsImage.get());
1270         m_pendingContentsImage = 0;
1271
1272         if (m_contentsLayerClones) {
1273             LayerMap::const_iterator end = m_contentsLayerClones->end();
1274             for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it)
1275                 it->second->setContents(m_contentsLayer->contents());
1276         }
1277         
1278         updateContentsRect();
1279     } else {
1280         // No image.
1281         // m_contentsLayer will be removed via updateSublayerList.
1282         m_contentsLayer = 0;
1283     }
1284 }
1285
1286 void GraphicsLayerCA::updateContentsMediaLayer()
1287 {
1288     // Video layer was set as m_contentsLayer, and will get parented in updateSublayerList().
1289     if (m_contentsLayer) {
1290         setupContentsLayer(m_contentsLayer.get());
1291         updateContentsRect();
1292     }
1293 }
1294
1295 void GraphicsLayerCA::updateContentsCanvasLayer()
1296 {
1297     // CanvasLayer was set as m_contentsLayer, and will get parented in updateSublayerList().
1298     if (m_contentsLayer) {
1299         setupContentsLayer(m_contentsLayer.get());
1300         m_contentsLayer->setNeedsDisplay();
1301         updateContentsRect();
1302     }
1303 }
1304
1305 void GraphicsLayerCA::updateContentsRect()
1306 {
1307     if (!m_contentsLayer)
1308         return;
1309
1310     FloatPoint point(m_contentsRect.x(), m_contentsRect.y());
1311     FloatRect rect(0, 0, m_contentsRect.width(), m_contentsRect.height());
1312
1313     m_contentsLayer->setPosition(point);
1314     m_contentsLayer->setBounds(rect);
1315
1316     if (m_contentsLayerClones) {
1317         LayerMap::const_iterator end = m_contentsLayerClones->end();
1318         for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it) {
1319             it->second->setPosition(point);
1320             it->second->setBounds(rect);
1321         }
1322     }
1323 }
1324
1325 void GraphicsLayerCA::updateMaskLayer()
1326 {
1327     PlatformCALayer* maskCALayer = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayer() : 0;
1328     m_layer->setMask(maskCALayer);
1329
1330     LayerMap* maskLayerCloneMap = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayerClones() : 0;
1331     
1332     if (LayerMap* layerCloneMap = m_layerClones.get()) {
1333         LayerMap::const_iterator end = layerCloneMap->end();
1334         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {            
1335             PlatformCALayer* maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(it->first).get() : 0;
1336             it->second->setMask(maskClone);
1337         }
1338     }
1339 }
1340
1341 void GraphicsLayerCA::updateReplicatedLayers()
1342 {
1343     // Clone the descendants of the replicated layer, and parent under us.
1344     ReplicaState replicaState(ReplicaState::ReplicaBranch);
1345
1346     RefPtr<PlatformCALayer>replicaRoot = replicatedLayerRoot(replicaState);
1347     if (!replicaRoot)
1348         return;
1349
1350     if (m_structuralLayer)
1351         m_structuralLayer->insertSublayer(replicaRoot.get(), 0);
1352     else
1353         m_layer->insertSublayer(replicaRoot.get(), 0);
1354 }
1355
1356 // For now, this assumes that layers only ever have one replica, so replicaIndices contains only 0 and 1.
1357 GraphicsLayerCA::CloneID GraphicsLayerCA::ReplicaState::cloneID() const
1358 {
1359     size_t depth = m_replicaBranches.size();
1360
1361     const size_t bitsPerUChar = sizeof(UChar) * 8;
1362     size_t vectorSize = (depth + bitsPerUChar - 1) / bitsPerUChar;
1363     
1364     Vector<UChar> result(vectorSize);
1365     result.fill(0);
1366
1367     // Create a string from the bit sequence which we can use to identify the clone.
1368     // Note that the string may contain embedded nulls, but that's OK.
1369     for (size_t i = 0; i < depth; ++i) {
1370         UChar& currChar = result[i / bitsPerUChar];
1371         currChar = (currChar << 1) | m_replicaBranches[i];
1372     }
1373     
1374     return String::adopt(result);
1375 }
1376
1377 PassRefPtr<PlatformCALayer> GraphicsLayerCA::replicatedLayerRoot(ReplicaState& replicaState)
1378 {
1379     // Limit replica nesting, to avoid 2^N explosion of replica layers.
1380     if (!m_replicatedLayer || replicaState.replicaDepth() == ReplicaState::maxReplicaDepth)
1381         return 0;
1382
1383     GraphicsLayerCA* replicatedLayer = static_cast<GraphicsLayerCA*>(m_replicatedLayer);
1384     
1385     RefPtr<PlatformCALayer> clonedLayerRoot = replicatedLayer->fetchCloneLayers(this, replicaState, RootCloneLevel);
1386     FloatPoint cloneRootPosition = replicatedLayer->positionForCloneRootLayer();
1387
1388     // Replica root has no offset or transform
1389     clonedLayerRoot->setPosition(cloneRootPosition);
1390     clonedLayerRoot->setTransform(TransformationMatrix());
1391
1392     return clonedLayerRoot;
1393 }
1394
1395 void GraphicsLayerCA::updateLayerAnimations()
1396 {
1397     if (m_animationsToProcess.size()) {
1398         AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
1399         for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
1400             const String& currAnimationName = it->first;
1401             AnimationsMap::iterator animationIt = m_runningAnimations.find(currAnimationName);
1402             if (animationIt == m_runningAnimations.end())
1403                 continue;
1404
1405             const AnimationProcessingAction& processingInfo = it->second;
1406             const Vector<LayerPropertyAnimation>& animations = animationIt->second;
1407             for (size_t i = 0; i < animations.size(); ++i) {
1408                 const LayerPropertyAnimation& currAnimation = animations[i];
1409                 switch (processingInfo.action) {
1410                 case Remove:
1411                     removeCAAnimationFromLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index);
1412                     break;
1413                 case Pause:
1414                     pauseCAAnimationOnLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, processingInfo.timeOffset);
1415                     break;
1416                 }
1417             }
1418
1419             if (processingInfo.action == Remove)
1420                 m_runningAnimations.remove(currAnimationName);
1421         }
1422     
1423         m_animationsToProcess.clear();
1424     }
1425     
1426     size_t numAnimations;
1427     if ((numAnimations = m_uncomittedAnimations.size())) {
1428         for (size_t i = 0; i < numAnimations; ++i) {
1429             const LayerPropertyAnimation& pendingAnimation = m_uncomittedAnimations[i];
1430             setAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_name, pendingAnimation.m_index, pendingAnimation.m_timeOffset);
1431             
1432             AnimationsMap::iterator it = m_runningAnimations.find(pendingAnimation.m_name);
1433             if (it == m_runningAnimations.end()) {
1434                 Vector<LayerPropertyAnimation> animations;
1435                 animations.append(pendingAnimation);
1436                 m_runningAnimations.add(pendingAnimation.m_name, animations);
1437             } else {
1438                 Vector<LayerPropertyAnimation>& animations = it->second;
1439                 animations.append(pendingAnimation);
1440             }
1441         }
1442         
1443         m_uncomittedAnimations.clear();
1444     }
1445 }
1446
1447 void GraphicsLayerCA::setAnimationOnLayer(PlatformCAAnimation* caAnim, AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
1448 {
1449     PlatformCALayer* layer = animatedLayer(property);
1450     
1451     if (timeOffset)
1452         caAnim->setBeginTime(CACurrentMediaTime() - timeOffset);
1453
1454     String animationID = animationIdentifier(animationName, property, index);
1455
1456     layer->removeAnimationForKey(animationID);
1457     layer->addAnimationForKey(animationID, caAnim);
1458
1459     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1460         LayerMap::const_iterator end = layerCloneMap->end();
1461         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1462             // Skip immediate replicas, since they move with the original.
1463             if (m_replicaLayer && isReplicatedRootClone(it->first))
1464                 continue;
1465
1466             it->second->removeAnimationForKey(animationID);
1467             it->second->addAnimationForKey(animationID, caAnim);
1468         }
1469     }
1470 }
1471
1472 // Workaround for <rdar://problem/7311367>
1473 static void bug7311367Workaround(PlatformCALayer* transformLayer, const TransformationMatrix& transform)
1474 {
1475     if (!transformLayer)
1476         return;
1477
1478     TransformationMatrix caTransform = transform;
1479     caTransform.setM41(caTransform.m41() + 1);
1480     transformLayer->setTransform(caTransform);
1481
1482     caTransform.setM41(caTransform.m41() - 1);
1483     transformLayer->setTransform(caTransform);
1484 }
1485
1486 bool GraphicsLayerCA::removeCAAnimationFromLayer(AnimatedPropertyID property, const String& animationName, int index)
1487 {
1488     PlatformCALayer* layer = animatedLayer(property);
1489
1490     String animationID = animationIdentifier(animationName, property, index);
1491
1492     if (!layer->animationForKey(animationID))
1493         return false;
1494     
1495     layer->removeAnimationForKey(animationID);
1496     bug7311367Workaround(m_structuralLayer.get(), m_transform);
1497
1498     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1499         LayerMap::const_iterator end = layerCloneMap->end();
1500         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1501             // Skip immediate replicas, since they move with the original.
1502             if (m_replicaLayer && isReplicatedRootClone(it->first))
1503                 continue;
1504
1505             it->second ->removeAnimationForKey(animationID);
1506         }
1507     }
1508     return true;
1509 }
1510
1511 void GraphicsLayerCA::pauseCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
1512 {
1513     PlatformCALayer* layer = animatedLayer(property);
1514
1515     String animationID = animationIdentifier(animationName, property, index);
1516
1517     RefPtr<PlatformCAAnimation> curAnim = layer->animationForKey(animationID);
1518     if (!curAnim)
1519         return;
1520
1521     // Animations on the layer are immutable, so we have to clone and modify.
1522     RefPtr<PlatformCAAnimation> newAnim = curAnim->copy();
1523
1524     newAnim->setSpeed(0);
1525     newAnim->setTimeOffset(timeOffset);
1526     
1527     layer->addAnimationForKey(animationID, newAnim.get()); // This will replace the running animation.
1528
1529     // Pause the animations on the clones too.
1530     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
1531         LayerMap::const_iterator end = layerCloneMap->end();
1532         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1533             // Skip immediate replicas, since they move with the original.
1534             if (m_replicaLayer && isReplicatedRootClone(it->first))
1535                 continue;
1536             it->second->addAnimationForKey(animationID, newAnim.get());
1537         }
1538     }
1539 }
1540
1541 void GraphicsLayerCA::repaintLayerDirtyRects()
1542 {
1543     if (!m_dirtyRects.size())
1544         return;
1545
1546     for (size_t i = 0; i < m_dirtyRects.size(); ++i)
1547         m_layer->setNeedsDisplay(&(m_dirtyRects[i]));
1548     
1549     m_dirtyRects.clear();
1550 }
1551
1552 void GraphicsLayerCA::updateContentsNeedsDisplay()
1553 {
1554     if (m_contentsLayer)
1555         m_contentsLayer->setNeedsDisplay();
1556 }
1557
1558 bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
1559 {
1560     ASSERT(valueList.property() != AnimatedPropertyWebkitTransform);
1561     
1562     bool isKeyframe = valueList.size() > 2;
1563     bool valuesOK;
1564     
1565     bool additive = false;
1566     int animationIndex = 0;
1567     
1568     RefPtr<PlatformCAAnimation> caAnimation;
1569     
1570     if (isKeyframe) {
1571         caAnimation = createKeyframeAnimation(animation, valueList.property(), additive);
1572         valuesOK = setAnimationKeyframes(valueList, animation, caAnimation.get());
1573     } else {
1574         caAnimation = createBasicAnimation(animation, valueList.property(), additive);
1575         valuesOK = setAnimationEndpoints(valueList, animation, caAnimation.get());
1576     }
1577     
1578     if (!valuesOK)
1579         return false;
1580
1581     m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
1582
1583     return true;
1584 }
1585
1586 bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset, const IntSize& boxSize)
1587 {
1588     ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
1589
1590     TransformOperationList functionList;
1591     bool listsMatch, hasBigRotation;
1592     fetchTransformOperationList(valueList, functionList, listsMatch, hasBigRotation);
1593
1594     // We need to fall back to software animation if we don't have setValueFunction:, and
1595     // we would need to animate each incoming transform function separately. This is the
1596     // case if we have a rotation >= 180 or we have more than one transform function.
1597     if ((hasBigRotation || functionList.size() > 1) && !PlatformCAAnimation::supportsValueFunction())
1598         return false;
1599
1600     bool validMatrices = true;
1601
1602     // If functionLists don't match we do a matrix animation, otherwise we do a component hardware animation.
1603     // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
1604     // if that's not true as well.
1605     bool isMatrixAnimation = !listsMatch || !PlatformCAAnimation::supportsValueFunction();
1606     
1607     size_t numAnimations = isMatrixAnimation ? 1 : functionList.size();
1608     bool isKeyframe = valueList.size() > 2;
1609     
1610     // Iterate through the transform functions, sending an animation for each one.
1611     for (size_t animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
1612         TransformOperation::OperationType transformOp = isMatrixAnimation ? TransformOperation::MATRIX_3D : functionList[animationIndex];
1613         RefPtr<PlatformCAAnimation> caAnimation;
1614
1615 #if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) || PLATFORM(WIN)
1616         // CA applies animations in reverse order (<rdar://problem/7095638>) so we need the last one we add (per property)
1617         // to be non-additive.
1618         // FIXME: This fix has not been added to QuartzCore on Windows yet (<rdar://problem/9112233>) so we expect the
1619         // reversed animation behavior
1620         bool additive = animationIndex < (numAnimations - 1);
1621 #else
1622         bool additive = animationIndex > 0;
1623 #endif
1624         if (isKeyframe) {
1625             caAnimation = createKeyframeAnimation(animation, valueList.property(), additive);
1626             validMatrices = setTransformAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
1627         } else {
1628             caAnimation = createBasicAnimation(animation, valueList.property(), additive);
1629             validMatrices = setTransformAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
1630         }
1631         
1632         if (!validMatrices)
1633             break;
1634     
1635         m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
1636     }
1637
1638     return validMatrices;
1639 }
1640
1641 PassRefPtr<PlatformCAAnimation> GraphicsLayerCA::createBasicAnimation(const Animation* anim, AnimatedPropertyID property, bool additive)
1642 {
1643     RefPtr<PlatformCAAnimation> basicAnim = PlatformCAAnimation::create(PlatformCAAnimation::Basic, propertyIdToString(property));
1644     setupAnimation(basicAnim.get(), anim, additive);
1645     return basicAnim;
1646 }
1647
1648 PassRefPtr<PlatformCAAnimation>GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, AnimatedPropertyID property, bool additive)
1649 {
1650     RefPtr<PlatformCAAnimation> keyframeAnim = PlatformCAAnimation::create(PlatformCAAnimation::Keyframe, propertyIdToString(property));
1651     setupAnimation(keyframeAnim.get(), anim, additive);
1652     return keyframeAnim;
1653 }
1654
1655 void GraphicsLayerCA::setupAnimation(PlatformCAAnimation* propertyAnim, const Animation* anim, bool additive)
1656 {
1657     double duration = anim->duration();
1658     if (duration <= 0)
1659         duration = cAnimationAlmostZeroDuration;
1660
1661     float repeatCount = anim->iterationCount();
1662     if (repeatCount == Animation::IterationCountInfinite)
1663         repeatCount = numeric_limits<float>::max();
1664     else if (anim->direction() == Animation::AnimationDirectionAlternate)
1665         repeatCount /= 2;
1666
1667     PlatformCAAnimation::FillModeType fillMode = PlatformCAAnimation::NoFillMode;
1668     switch (anim->fillMode()) {
1669     case AnimationFillModeNone:
1670         fillMode = PlatformCAAnimation::Forwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash.
1671         break;
1672     case AnimationFillModeBackwards:
1673         fillMode = PlatformCAAnimation::Both; // Use "both" rather than "backwards" because the style system will remove the animation when it is finished. This avoids a flash.
1674         break;
1675     case AnimationFillModeForwards:
1676         fillMode = PlatformCAAnimation::Forwards;
1677         break;
1678     case AnimationFillModeBoth:
1679         fillMode = PlatformCAAnimation::Both;
1680         break;
1681     }
1682
1683     propertyAnim->setDuration(duration);
1684     propertyAnim->setRepeatCount(repeatCount);
1685     propertyAnim->setAutoreverses(anim->direction());
1686     propertyAnim->setRemovedOnCompletion(false);
1687     propertyAnim->setAdditive(additive);
1688     propertyAnim->setFillMode(fillMode);
1689 }
1690
1691 const TimingFunction* GraphicsLayerCA::timingFunctionForAnimationValue(const AnimationValue* animValue, const Animation* anim)
1692 {
1693     if (animValue->timingFunction())
1694         return animValue->timingFunction();
1695     if (anim->isTimingFunctionSet())
1696         return anim->timingFunction().get();
1697     
1698     return CubicBezierTimingFunction::defaultTimingFunction();
1699 }
1700
1701 bool GraphicsLayerCA::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* anim, PlatformCAAnimation* basicAnim)
1702 {
1703     switch (valueList.property()) {
1704     case AnimatedPropertyOpacity: {
1705         basicAnim->setFromValue(static_cast<const FloatAnimationValue*>(valueList.at(0))->value());
1706         basicAnim->setToValue(static_cast<const FloatAnimationValue*>(valueList.at(1))->value());
1707         break;
1708     }
1709     default:
1710         ASSERT_NOT_REACHED(); // we don't animate color yet
1711         break;
1712     }
1713
1714     // This codepath is used for 2-keyframe animations, so we still need to look in the start
1715     // for a timing function.
1716     const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), anim);
1717     if (timingFunction)
1718         basicAnim->setTimingFunction(timingFunction);
1719
1720     return true;
1721 }
1722
1723 bool GraphicsLayerCA::setAnimationKeyframes(const KeyframeValueList& valueList, const Animation* anim, PlatformCAAnimation* keyframeAnim)
1724 {
1725     Vector<float> keyTimes;
1726     Vector<float> values;
1727     Vector<const TimingFunction*> timingFunctions;
1728     
1729     for (unsigned i = 0; i < valueList.size(); ++i) {
1730         const AnimationValue* curValue = valueList.at(i);
1731         keyTimes.append(curValue->keyTime());
1732
1733         switch (valueList.property()) {
1734         case AnimatedPropertyOpacity: {
1735             const FloatAnimationValue* floatValue = static_cast<const FloatAnimationValue*>(curValue);
1736             values.append(floatValue->value());
1737             break;
1738         }
1739         default:
1740             ASSERT_NOT_REACHED(); // we don't animate color yet
1741             break;
1742         }
1743
1744         timingFunctions.append(timingFunctionForAnimationValue(curValue, anim));
1745     }
1746     
1747     // We toss the last tfArray value because it has to one shorter than the others.
1748     timingFunctions.removeLast();
1749
1750     keyframeAnim->setKeyTimes(keyTimes);
1751     keyframeAnim->setValues(values);
1752     keyframeAnim->setTimingFunctions(timingFunctions);
1753     
1754     return true;
1755 }
1756
1757 bool GraphicsLayerCA::setTransformAnimationEndpoints(const KeyframeValueList& valueList, const Animation* anim, PlatformCAAnimation* basicAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
1758 {
1759     ASSERT(valueList.size() == 2);
1760     const TransformAnimationValue* startValue = static_cast<const TransformAnimationValue*>(valueList.at(0));
1761     const TransformAnimationValue* endValue = static_cast<const TransformAnimationValue*>(valueList.at(1));
1762     
1763     if (isMatrixAnimation) {
1764         TransformationMatrix fromTransform, toTransform;
1765         startValue->value()->apply(boxSize, fromTransform);
1766         endValue->value()->apply(boxSize, toTransform);
1767
1768         // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
1769         if (!fromTransform.isInvertible() || !toTransform.isInvertible())
1770             return false;
1771             
1772         basicAnim->setFromValue(fromTransform);
1773         basicAnim->setToValue(toTransform);
1774     } else {
1775         if (isTransformTypeNumber(transformOpType)) {
1776             float fromValue;
1777             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
1778             basicAnim->setFromValue(fromValue);
1779             
1780             float toValue;
1781             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
1782             basicAnim->setToValue(toValue);
1783         } else if (isTransformTypeFloatPoint3D(transformOpType)) {
1784             FloatPoint3D fromValue;
1785             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
1786             basicAnim->setFromValue(fromValue);
1787             
1788             FloatPoint3D toValue;
1789             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
1790             basicAnim->setToValue(toValue);
1791         } else {
1792             TransformationMatrix fromValue;
1793             getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
1794             basicAnim->setFromValue(fromValue);
1795
1796             TransformationMatrix toValue;
1797             getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
1798             basicAnim->setToValue(toValue);
1799         }
1800     }
1801
1802     // This codepath is used for 2-keyframe animations, so we still need to look in the start
1803     // for a timing function.
1804     const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), anim);
1805     basicAnim->setTimingFunction(timingFunction);
1806
1807 #if HAVE_MODERN_QUARTZCORE
1808     PlatformCAAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
1809     if (valueFunction != PlatformCAAnimation::NoValueFunction)
1810         basicAnim->setValueFunction(valueFunction);
1811 #endif
1812
1813     return true;
1814 }
1815
1816 bool GraphicsLayerCA::setTransformAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
1817 {
1818     Vector<float> keyTimes;
1819     Vector<float> floatValues;
1820     Vector<FloatPoint3D> floatPoint3DValues;
1821     Vector<TransformationMatrix> transformationMatrixValues;
1822     Vector<const TimingFunction*> timingFunctions;
1823
1824     for (unsigned i = 0; i < valueList.size(); ++i) {
1825         const TransformAnimationValue* curValue = static_cast<const TransformAnimationValue*>(valueList.at(i));
1826         keyTimes.append(curValue->keyTime());
1827
1828         if (isMatrixAnimation) {
1829             TransformationMatrix transform;
1830             curValue->value()->apply(boxSize, transform);
1831
1832             // If any matrix is singular, CA won't animate it correctly. So fall back to software animation
1833             if (!transform.isInvertible())
1834                 return false;
1835
1836             transformationMatrixValues.append(transform);
1837         } else {
1838             const TransformOperation* transformOp = curValue->value()->at(functionIndex);
1839             if (isTransformTypeNumber(transformOpType)) {
1840                 float value;
1841                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
1842                 floatValues.append(value);
1843             } else if (isTransformTypeFloatPoint3D(transformOpType)) {
1844                 FloatPoint3D value;
1845                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
1846                 floatPoint3DValues.append(value);
1847             } else {
1848                 TransformationMatrix value;
1849                 getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
1850                 transformationMatrixValues.append(value);
1851             }
1852         }
1853
1854         const TimingFunction* timingFunction = timingFunctionForAnimationValue(curValue, animation);
1855         timingFunctions.append(timingFunction);
1856     }
1857     
1858     // We toss the last tfArray value because it has to one shorter than the others.
1859     timingFunctions.removeLast();
1860
1861     keyframeAnim->setKeyTimes(keyTimes);
1862     
1863     if (isTransformTypeNumber(transformOpType))
1864         keyframeAnim->setValues(floatValues);
1865     else if (isTransformTypeFloatPoint3D(transformOpType))
1866         keyframeAnim->setValues(floatPoint3DValues);
1867     else
1868         keyframeAnim->setValues(transformationMatrixValues);
1869         
1870     keyframeAnim->setTimingFunctions(timingFunctions);
1871
1872 #if HAVE_MODERN_QUARTZCORE
1873     PlatformCAAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
1874     if (valueFunction != PlatformCAAnimation::NoValueFunction)
1875         keyframeAnim->setValueFunction(valueFunction);
1876 #endif
1877     return true;
1878 }
1879
1880 void GraphicsLayerCA::suspendAnimations(double time)
1881 {
1882     double t = PlatformCALayer::currentTimeToMediaTime(time ? time : currentTime());
1883     primaryLayer()->setSpeed(0);
1884     primaryLayer()->setTimeOffset(t);
1885
1886     // Suspend the animations on the clones too.
1887     if (LayerMap* layerCloneMap = primaryLayerClones()) {
1888         LayerMap::const_iterator end = layerCloneMap->end();
1889         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1890             it->second->setSpeed(0);
1891             it->second->setTimeOffset(t);
1892         }
1893     }
1894 }
1895
1896 void GraphicsLayerCA::resumeAnimations()
1897 {
1898     primaryLayer()->setSpeed(1);
1899     primaryLayer()->setTimeOffset(0);
1900
1901     // Resume the animations on the clones too.
1902     if (LayerMap* layerCloneMap = primaryLayerClones()) {
1903         LayerMap::const_iterator end = layerCloneMap->end();
1904         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
1905             it->second->setSpeed(1);
1906             it->second->setTimeOffset(0);
1907         }
1908     }
1909 }
1910
1911 PlatformCALayer* GraphicsLayerCA::hostLayerForSublayers() const
1912 {
1913     return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); 
1914 }
1915
1916 PlatformCALayer* GraphicsLayerCA::layerForSuperlayer() const
1917 {
1918     return m_structuralLayer ? m_structuralLayer.get() : m_layer.get();
1919 }
1920
1921 PlatformCALayer* GraphicsLayerCA::animatedLayer(AnimatedPropertyID property) const
1922 {
1923     return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayer.get() : primaryLayer();
1924 }
1925
1926 GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedPropertyID property) const
1927 {
1928     return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones();
1929 }
1930
1931 void GraphicsLayerCA::setContentsScale(float scale)
1932 {
1933     float newScale = clampedContentsScaleForScale(scale);
1934     if (newScale == m_contentsScale)
1935         return;
1936
1937     m_contentsScale = newScale;
1938     noteLayerPropertyChanged(ContentsScaleChanged);
1939 }
1940
1941 float GraphicsLayerCA::clampedContentsScaleForScale(float scale) const
1942 {
1943     // Define some limits as a sanity check for the incoming scale value
1944     // those too small to see.
1945     const float maxScale = 5.0f;
1946     const float minScale = 0.01f;
1947     
1948     // Avoid very slight scale changes that would be doing extra work for no benefit
1949     const float maxAllowableDelta = 0.05f;
1950
1951     // Clamp
1952     float result = max(minScale, min(scale, maxScale));
1953
1954     // If it hasn't changed much, don't do any work
1955     return ((fabs(result - m_contentsScale) / m_contentsScale) < maxAllowableDelta) ? m_contentsScale : result;
1956 }
1957
1958 void GraphicsLayerCA::updateContentsScale()
1959 {
1960     bool needTiledLayer = requiresTiledLayer(m_size);
1961     if (needTiledLayer != m_usingTiledLayer)
1962         swapFromOrToTiledLayer(needTiledLayer);
1963
1964     m_layer->setContentsScale(m_contentsScale);
1965     if (drawsContent())
1966         m_layer->setNeedsDisplay();
1967 }
1968
1969 void GraphicsLayerCA::setDebugBackgroundColor(const Color& color)
1970 {    
1971     if (color.isValid())
1972         m_layer->setBackgroundColor(color);
1973     else
1974         m_layer->setBackgroundColor(Color::transparent);
1975 }
1976
1977 void GraphicsLayerCA::setDebugBorder(const Color& color, float borderWidth)
1978 {    
1979     if (color.isValid()) {
1980         m_layer->setBorderColor(color);
1981         m_layer->setBorderWidth(borderWidth);
1982     } else {
1983         m_layer->setBorderColor(Color::transparent);
1984         m_layer->setBorderWidth(0);
1985     }
1986 }
1987
1988 FloatSize GraphicsLayerCA::constrainedSize() const
1989 {
1990     float tileColumns = ceilf(m_size.width() / kTiledLayerTileSize);
1991     float tileRows = ceilf(m_size.height() / kTiledLayerTileSize);
1992     double numTiles = tileColumns * tileRows;
1993     
1994     FloatSize constrainedSize = m_size;
1995     const unsigned cMaxTileCount = 512;
1996     while (numTiles > cMaxTileCount) {
1997         // Constrain the wider dimension.
1998         if (constrainedSize.width() >= constrainedSize.height()) {
1999             tileColumns = max(floorf(cMaxTileCount / tileRows), 1.0f);
2000             constrainedSize.setWidth(tileColumns * kTiledLayerTileSize);
2001         } else {
2002             tileRows = max(floorf(cMaxTileCount / tileColumns), 1.0f);
2003             constrainedSize.setHeight(tileRows * kTiledLayerTileSize);
2004         }
2005         numTiles = tileColumns * tileRows;
2006     }
2007     
2008     return constrainedSize;
2009 }
2010
2011 bool GraphicsLayerCA::requiresTiledLayer(const FloatSize& size) const
2012 {
2013     if (!m_drawsContent || !m_allowTiledLayer)
2014         return false;
2015
2016     // FIXME: catch zero-size height or width here (or earlier)?
2017     return size.width() > cMaxPixelDimension || size.height() > cMaxPixelDimension;
2018 }
2019
2020 void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer)
2021 {
2022     ASSERT(useTiledLayer != m_usingTiledLayer);
2023     RefPtr<PlatformCALayer> oldLayer = m_layer;
2024     
2025     m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeWebTiledLayer : PlatformCALayer::LayerTypeWebLayer, this);
2026     m_layer->setContentsScale(m_contentsScale);
2027
2028     m_usingTiledLayer = useTiledLayer;
2029     
2030     if (useTiledLayer) {
2031 #if !HAVE_MODERN_QUARTZCORE
2032         // Tiled layer has issues with flipped coordinates.
2033         setContentsOrientation(CompositingCoordinatesTopDown);
2034 #endif
2035     } else {
2036 #if !HAVE_MODERN_QUARTZCORE
2037         setContentsOrientation(GraphicsLayerCA::defaultContentsOrientation());
2038 #endif
2039     }
2040
2041     m_layer->adoptSublayers(oldLayer.get());
2042     
2043     // If m_layer doesn't have a parent, it means it's the root layer and
2044     // is likely hosted by something that is not expecting to be changed
2045     ASSERT(oldLayer->superlayer());
2046     oldLayer->superlayer()->replaceSublayer(oldLayer.get(), m_layer.get());
2047
2048     updateContentsTransform();
2049
2050     updateLayerPosition();
2051     updateLayerSize();
2052     updateAnchorPoint();
2053     updateTransform();
2054     updateChildrenTransform();
2055     updateMasksToBounds();
2056     updateContentsOpaque();
2057     updateBackfaceVisibility();
2058     updateLayerBackgroundColor();
2059     
2060     updateOpacityOnLayer();
2061     
2062 #ifndef NDEBUG
2063     String name = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer.get(), this) + m_name;
2064     m_layer->setName(name);
2065 #endif
2066
2067     // move over animations
2068     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, oldLayer.get(), m_layer.get());
2069     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, oldLayer.get(), m_layer.get());
2070     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyBackgroundColor, oldLayer.get(), m_layer.get());
2071     
2072     // need to tell new layer to draw itself
2073     setNeedsDisplay();
2074     
2075     updateDebugIndicators();
2076 }
2077
2078 GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayerCA::defaultContentsOrientation() const
2079 {
2080 #if !HAVE_MODERN_QUARTZCORE
2081     // Older QuartzCore does not support -geometryFlipped, so we manually flip the root
2082     // layer geometry, and then flip the contents of each layer back so that the CTM for CG
2083     // is unflipped, allowing it to do the correct font auto-hinting.
2084     return CompositingCoordinatesBottomUp;
2085 #else
2086     return CompositingCoordinatesTopDown;
2087 #endif
2088 }
2089
2090 void GraphicsLayerCA::updateContentsTransform()
2091 {
2092 #if !HAVE_MODERN_QUARTZCORE
2093     if (contentsOrientation() == CompositingCoordinatesBottomUp) {
2094         CGAffineTransform contentsTransform = CGAffineTransformMakeScale(1, -1);
2095         contentsTransform = CGAffineTransformTranslate(contentsTransform, 0, -m_layer->bounds().size().height());
2096         m_layer->setContentsTransform(TransformationMatrix(contentsTransform));
2097     }
2098 #endif
2099 }
2100
2101 void GraphicsLayerCA::setupContentsLayer(PlatformCALayer* contentsLayer)
2102 {
2103     // Turn off implicit animations on the inner layer.
2104     contentsLayer->setMasksToBounds(true);
2105
2106     if (defaultContentsOrientation() == CompositingCoordinatesBottomUp) {
2107         TransformationMatrix flipper(
2108             1.0f, 0.0f, 0.0f, 0.0f,
2109             0.0f, -1.0f, 0.0f, 0.0f,
2110             0.0f, 0.0f, 1.0f, 0.0f,
2111             0.0f, 0.0f, 0.0f, 1.0f);
2112         contentsLayer->setTransform(flipper);
2113         contentsLayer->setAnchorPoint(FloatPoint3D(0, 1, 0));
2114     } else
2115         contentsLayer->setAnchorPoint(FloatPoint3D());
2116
2117     if (showDebugBorders()) {
2118         contentsLayer->setBorderColor(Color(0, 0, 128, 180));
2119         contentsLayer->setBorderWidth(1.0f);
2120     }
2121 }
2122
2123 PassRefPtr<PlatformCALayer> GraphicsLayerCA::findOrMakeClone(CloneID cloneID, PlatformCALayer *sourceLayer, LayerMap* clones, CloneLevel cloneLevel)
2124 {
2125     if (!sourceLayer)
2126         return 0;
2127
2128     RefPtr<PlatformCALayer> resultLayer;
2129
2130     // Add with a dummy value to get an iterator for the insertion position, and a boolean that tells
2131     // us whether there's an item there. This technique avoids two hash lookups.
2132     RefPtr<PlatformCALayer> dummy;
2133     pair<LayerMap::iterator, bool> addResult = clones->add(cloneID, dummy);
2134     if (!addResult.second) {
2135         // Value was not added, so it exists already.
2136         resultLayer = addResult.first->second.get();
2137     } else {
2138         resultLayer = cloneLayer(sourceLayer, cloneLevel);
2139 #ifndef NDEBUG
2140         resultLayer->setName(String::format("Clone %d of layer %p", cloneID[0U], sourceLayer));
2141 #endif
2142         addResult.first->second = resultLayer;
2143     }
2144
2145     return resultLayer;
2146 }   
2147
2148 void GraphicsLayerCA::ensureCloneLayers(CloneID cloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer, RefPtr<PlatformCALayer>& contentsLayer, CloneLevel cloneLevel)
2149 {
2150     structuralLayer = 0;
2151     contentsLayer = 0;
2152
2153     if (!m_layerClones)
2154         m_layerClones = adoptPtr(new LayerMap);
2155
2156     if (!m_structuralLayerClones && m_structuralLayer)
2157         m_structuralLayerClones = adoptPtr(new LayerMap);
2158
2159     if (!m_contentsLayerClones && m_contentsLayer)
2160         m_contentsLayerClones = adoptPtr(new LayerMap);
2161
2162     primaryLayer = findOrMakeClone(cloneID, m_layer.get(), m_layerClones.get(), cloneLevel);
2163     structuralLayer = findOrMakeClone(cloneID, m_structuralLayer.get(), m_structuralLayerClones.get(), cloneLevel);
2164     contentsLayer = findOrMakeClone(cloneID, m_contentsLayer.get(), m_contentsLayerClones.get(), cloneLevel);
2165 }
2166
2167 void GraphicsLayerCA::removeCloneLayers()
2168 {
2169     m_layerClones = nullptr;
2170     m_structuralLayerClones = nullptr;
2171     m_contentsLayerClones = nullptr;
2172 }
2173
2174 FloatPoint GraphicsLayerCA::positionForCloneRootLayer() const
2175 {
2176     // This can get called during a sync when we've just removed the m_replicaLayer.
2177     if (!m_replicaLayer)
2178         return FloatPoint();
2179
2180     FloatPoint replicaPosition = m_replicaLayer->replicatedLayerPosition();
2181     return FloatPoint(replicaPosition.x() + m_anchorPoint.x() * m_size.width(),
2182                       replicaPosition.y() + m_anchorPoint.y() * m_size.height());
2183 }
2184
2185 void GraphicsLayerCA::propagateLayerChangeToReplicas()
2186 {
2187     for (GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) {
2188         GraphicsLayerCA* currLayerCA = static_cast<GraphicsLayerCA*>(currLayer);
2189         if (!currLayerCA->hasCloneLayers())
2190             break;
2191
2192         if (currLayerCA->replicaLayer())
2193             static_cast<GraphicsLayerCA*>(currLayerCA->replicaLayer())->noteLayerPropertyChanged(ReplicatedLayerChanged);
2194     }
2195 }
2196
2197 PassRefPtr<PlatformCALayer> GraphicsLayerCA::fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState& replicaState, CloneLevel cloneLevel)
2198 {
2199     RefPtr<PlatformCALayer> primaryLayer;
2200     RefPtr<PlatformCALayer> structuralLayer;
2201     RefPtr<PlatformCALayer> contentsLayer;
2202     ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, cloneLevel);
2203
2204     if (m_maskLayer) {
2205         RefPtr<PlatformCALayer> maskClone = static_cast<GraphicsLayerCA*>(m_maskLayer)->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
2206         primaryLayer->setMask(maskClone.get());
2207     }
2208
2209     if (m_replicatedLayer) {
2210         // We are a replica being asked for clones of our layers.
2211         RefPtr<PlatformCALayer> replicaRoot = replicatedLayerRoot(replicaState);
2212         if (!replicaRoot)
2213             return 0;
2214
2215         if (structuralLayer) {
2216             structuralLayer->insertSublayer(replicaRoot.get(), 0);
2217             return structuralLayer;
2218         }
2219         
2220         primaryLayer->insertSublayer(replicaRoot.get(), 0);
2221         return primaryLayer;
2222     }
2223
2224     const Vector<GraphicsLayer*>& childLayers = children();
2225     Vector<RefPtr<PlatformCALayer> > clonalSublayers;
2226
2227     RefPtr<PlatformCALayer> replicaLayer;
2228     
2229     if (m_replicaLayer && m_replicaLayer != replicaRoot) {
2230         // We have nested replicas. Ask the replica layer for a clone of its contents.
2231         replicaState.setBranchType(ReplicaState::ReplicaBranch);
2232         replicaLayer = static_cast<GraphicsLayerCA*>(m_replicaLayer)->fetchCloneLayers(replicaRoot, replicaState, RootCloneLevel);
2233         replicaState.setBranchType(ReplicaState::ChildBranch);
2234     }
2235     
2236     if (replicaLayer || structuralLayer || contentsLayer || childLayers.size() > 0) {
2237         if (structuralLayer) {
2238             // Replicas render behind the actual layer content.
2239             if (replicaLayer)
2240                 clonalSublayers.append(replicaLayer);
2241                 
2242             // Add the primary layer next. Even if we have negative z-order children, the primary layer always comes behind.
2243             clonalSublayers.append(primaryLayer);
2244         } else if (contentsLayer) {
2245             // FIXME: add the contents layer in the correct order with negative z-order children.
2246             // This does not cause visible rendering issues because currently contents layers are only used
2247             // for replaced elements that don't have children.
2248             clonalSublayers.append(contentsLayer);
2249         }
2250         
2251         replicaState.push(ReplicaState::ChildBranch);
2252
2253         size_t numChildren = childLayers.size();
2254         for (size_t i = 0; i < numChildren; ++i) {
2255             GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
2256
2257             RefPtr<PlatformCALayer> childLayer = curChild->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
2258             if (childLayer)
2259                 clonalSublayers.append(childLayer);
2260         }
2261
2262         replicaState.pop();
2263
2264         for (size_t i = 0; i < clonalSublayers.size(); ++i)
2265             clonalSublayers[i]->removeFromSuperlayer();
2266     }
2267     
2268     RefPtr<PlatformCALayer> result;
2269     if (structuralLayer) {
2270         structuralLayer->setSublayers(clonalSublayers);
2271
2272         if (contentsLayer) {
2273             // If we have a transform layer, then the contents layer is parented in the 
2274             // primary layer (which is itself a child of the transform layer).
2275             primaryLayer->removeAllSublayers();
2276             primaryLayer->appendSublayer(contentsLayer.get());
2277         }
2278
2279         result = structuralLayer;
2280     } else {
2281         primaryLayer->setSublayers(clonalSublayers);
2282         result = primaryLayer;
2283     }
2284
2285     return result;
2286 }
2287
2288 PassRefPtr<PlatformCALayer> GraphicsLayerCA::cloneLayer(PlatformCALayer *layer, CloneLevel cloneLevel)
2289 {
2290     PlatformCALayer::LayerType layerType = (layer->layerType() == PlatformCALayer::LayerTypeTransformLayer) ? 
2291                                                 PlatformCALayer::LayerTypeTransformLayer : PlatformCALayer::LayerTypeLayer;
2292     RefPtr<PlatformCALayer> newLayer = PlatformCALayer::create(layerType, this);
2293     
2294     newLayer->setPosition(layer->position());
2295     newLayer->setBounds(layer->bounds());
2296     newLayer->setAnchorPoint(layer->anchorPoint());
2297     newLayer->setTransform(layer->transform());
2298     newLayer->setSublayerTransform(layer->sublayerTransform());
2299     newLayer->setContents(layer->contents());
2300     newLayer->setMasksToBounds(layer->masksToBounds());
2301     newLayer->setDoubleSided(layer->isDoubleSided());
2302     newLayer->setOpaque(layer->isOpaque());
2303     newLayer->setBackgroundColor(layer->backgroundColor());
2304     newLayer->setContentsScale(layer->contentsScale());
2305
2306     if (cloneLevel == IntermediateCloneLevel) {
2307         newLayer->setOpacity(layer->opacity());
2308         moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyWebkitTransform, layer, newLayer.get());
2309         moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyOpacity, layer, newLayer.get());
2310     }
2311     
2312     if (showDebugBorders()) {
2313         newLayer->setBorderColor(Color(255, 122, 251));
2314         newLayer->setBorderWidth(2);
2315     }
2316     
2317     return newLayer;
2318 }
2319
2320 void GraphicsLayerCA::setOpacityInternal(float accumulatedOpacity)
2321 {
2322     LayerMap* layerCloneMap = 0;
2323     
2324     if (preserves3D()) {
2325         m_layer->setOpacity(accumulatedOpacity);
2326         layerCloneMap = m_layerClones.get();
2327     } else {
2328         primaryLayer()->setOpacity(accumulatedOpacity);
2329         layerCloneMap = primaryLayerClones();
2330     }
2331
2332     if (layerCloneMap) {
2333         LayerMap::const_iterator end = layerCloneMap->end();
2334         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2335             if (m_replicaLayer && isReplicatedRootClone(it->first))
2336                 continue;
2337             it->second->setOpacity(m_opacity);
2338         }
2339     }
2340 }
2341
2342 void GraphicsLayerCA::updateOpacityOnLayer()
2343 {
2344 #if !HAVE_MODERN_QUARTZCORE
2345     // Distribute opacity either to our own layer or to our children. We pass in the 
2346     // contribution from our parent(s).
2347     distributeOpacity(parent() ? parent()->accumulatedOpacity() : 1);
2348 #else
2349     primaryLayer()->setOpacity(m_opacity);
2350
2351     if (LayerMap* layerCloneMap = primaryLayerClones()) {
2352         LayerMap::const_iterator end = layerCloneMap->end();
2353         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
2354             if (m_replicaLayer && isReplicatedRootClone(it->first))
2355                 continue;
2356
2357             it->second->setOpacity(m_opacity);
2358         }
2359         
2360     }
2361 #endif
2362 }
2363
2364 void GraphicsLayerCA::noteSublayersChanged()
2365 {
2366     noteLayerPropertyChanged(ChildrenChanged);
2367     propagateLayerChangeToReplicas();
2368 }
2369
2370 void GraphicsLayerCA::noteLayerPropertyChanged(LayerChangeFlags flags)
2371 {
2372     if (!m_uncommittedChanges && m_client)
2373         m_client->notifySyncRequired(this);
2374
2375     m_uncommittedChanges |= flags;
2376 }
2377
2378 } // namespace WebCore
2379
2380 #endif // USE(ACCELERATED_COMPOSITING)