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